1 /**********************************************************************************************************************
3 * Copyright (C) 2012 Continental Automotive Systems, Inc.
5 * Author: Jean-Pierre.Bogler@continental-corporation.com
7 * Implementation of the NodeStateManager
9 * The NodeStateManager (NSM) is a central state manager for the system node. It manages the "NodeState",
10 * the "ApplicationMode" and many other states of the complete system. In addition, the NSM offers a
11 * session handling and a shutdown management.
12 * The NSM communicates with the NodeStateMachine (NSMC) to request and inform it about state changes
13 * and the NodeStateAccess (NSMA) to connect to the D-Bus.
15 * This Source Code Form is subject to the terms of the Mozilla Public
16 * License, v. 2.0. If a copy of the MPL was not distributed with this
17 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
20 * 20.06.2012 Jean-Pierre Bogler CSP_WZ#388: Initial creation
21 * 19.09.2012 Jean-Pierre Bogler OvipRbt#135: Added new default sessions for product, thermal and power
22 * management. Fixed bug, when calling 'GetSessionState'.
23 * Undefined parameter 'SessionOwner' was used.
24 * 27.09.2012 Jean-Pierre Bogler CSP_WZ#1194: Changed file header structure and license to be released
25 * as open source package. Introduced 'NodeStateTypes.h' to
26 * avoid circle includes and encapsulate type definitions.
27 * 08.10.2012 Jean-Pierre Bogler CSP_WZ#951: Introduced improvements and changes from 4-eye review:
28 * - Changed handling of failed applications
29 * - Changed handling of platform sessions
30 * - Fixed some QAC warnings
31 * - Added deallocation of GError objects
32 * 24.10.2012 Jean-Pierre Bogler CSP_WZ#1322: The NSM does not use generated D-Bus objects anymore,
33 * due to legal restrictions. Instead, it registers
34 * callbacks at the NodeStateAccess library NSMA.
35 * Therefore, the parameters of the callbacks changed.
36 * In addition, the establishment of the connection and
37 * the handling of life cycle clients (timeout observation)
38 * is done by the NSMA.
39 * 01.11.2012 C. Domke CSP_WZ#666: Instrumented with LTPRO messages
40 * 10.01.2013 Jean-Pierre Bogler CSP_WZ#1322: Initialize variables at declaration instead of using
41 * memset and use g_utf8_strlen instead of strlen to
42 * simplify configure srcipt (avoid some checks).
44 **********************************************************************************************************************/
47 /**********************************************************************************************************************
51 **********************************************************************************************************************/
52 #include "NodeStateManager.h" /* Own Header file */
53 #include "NodeStateTypes.h" /* Typedefinitions to use the NSM */
54 #include "string.h" /* Memcpy etc. */
55 #include "gio/gio.h" /* GLib lists */
56 #include "dlt/dlt.h" /* DLT Log'n'Trace */
57 #include "NodeStateMachine.h" /* Talk to NodeStateMachine */
58 #include "NodeStateAccess.h" /* Access the IPC (D-Bus) */
59 #include "syslog.h" /* Syslog messages */
61 /**********************************************************************************************************************
63 * Local defines, macros and type definitions.
65 **********************************************************************************************************************/
67 /* The type defines the structure for a lifecycle consumer client */
70 gchar *sBusName; /* Bus name of the lifecycle client */
71 gchar *sObjName; /* Object path of the client */
72 guint32 u32RegisteredMode; /* Bit array of shutdown modes */
73 NSMA_tLcConsumerHandle hClient; /* Handle for proxy object for lifecycle client */
74 gboolean boShutdown; /* Only "run up" clients which are shut down */
75 } NSM__tstLifecycleClient;
78 /* The type is used to store failed applications. A struct is used to allow extsions in future */
81 gchar sName[NSM_MAX_SESSION_OWNER_LENGTH];
82 } NSM__tstFailedApplication;
85 /* List of names for the available default sessions, will are automatically provided by NSM */
86 static const gchar* NSM__asDefaultSessions[] = { "DiagnosisSession",
89 "NetworkActiveSession",
90 "NetworkPassiveSession",
92 "PermanentModeSession",
97 "PlatformThermalSession",
98 "PlatformSupplySession",
102 /**********************************************************************************************************************
104 * Prototypes for file local functions (see implementation for description)
106 **********************************************************************************************************************/
108 /* Helper functions to destruct objects */
109 static void NSM__vFreeFailedApplicationObject(gpointer pFailedApplication);
110 static void NSM__vFreeSessionObject (gpointer pSession );
111 static void NSM__vFreeLifecycleClientObject (gpointer pLifecycleClient );
114 /* Helper functions to compare objects in lists */
115 static gboolean NSM__boIsPlatformSession (NsmSession_s *pstSession);
116 static gint NSM__i32LifecycleClientCompare (gconstpointer pL1, gconstpointer pL2);
117 static gint NSM__i32SessionOwnerNameSeatCompare(gconstpointer pS1, gconstpointer pS2);
118 static gint NSM__i32SessionNameSeatCompare (gconstpointer pS1, gconstpointer pS2);
119 static gint NSM__i32SessionOwnerCompare (gconstpointer pS1, gconstpointer pS2);
120 static gint NSM__i32ApplicationCompare (gconstpointer pA1, gconstpointer pA2);
123 /* Helper functions to recognize failed applications and disable their sessions */
124 static void NSM__vDisableSessionsForApp(NSM__tstFailedApplication* pstFailedApp);
125 static NsmErrorStatus_e NSM__enSetAppStateFailed (NSM__tstFailedApplication* pstFailedApp);
126 static NsmErrorStatus_e NSM__enSetAppStateValid (NSM__tstFailedApplication* pstFailedApp);
129 /* Helper functions to control and start the "lifecycle request" sequence */
130 static void NSM__vCallNextLifecycleClient(void);
131 static void NSM__vOnLifecycleRequestFinish(const NsmErrorStatus_e enErrorStatus);
134 /* Internal functions, to set and get values. Indirectly used by D-Bus and StateMachine */
135 static NsmErrorStatus_e NSM__enSetNodeState (NsmNodeState_e enNodeState,
136 gboolean boInformBus,
137 gboolean boInformMachine);
138 static NsmErrorStatus_e NSM__enSetBootMode (const gint i32BootMode,
139 gboolean boInformMachine);
140 static NsmErrorStatus_e NSM__enSetApplicationMode (NsmApplicationMode_e enApplicationMode,
141 gboolean boInformBus,
142 gboolean boInformMachine);
143 static NsmErrorStatus_e NSM__enSetShutdownReason (NsmShutdownReason_e enNewShutdownReason,
144 gboolean boInformMachine);
146 static void NSM__vPublishSessionChange (NsmSession_s *pstChangedSession,
147 gboolean boInformBus,
148 gboolean boInformMachine);
149 static NsmErrorStatus_e NSM__enSetDefaultSessionState(NsmSession_s *pstSession,
150 gboolean boInformBus,
151 gboolean boInformMachine);
152 static NsmErrorStatus_e NSM__enSetProductSessionState(NsmSession_s *pstSession,
153 gboolean boInformBus,
154 gboolean boInformMachine);
155 static NsmErrorStatus_e NSM__enSetSessionState (NsmSession_s *pstSession,
156 gboolean boInformBus,
157 gboolean boInformMachine);
158 static NsmErrorStatus_e NSM__enGetSessionState (NsmSession_s *pstSession);
161 /* Internal functions that are directly used from D-Bus and StateMachine */
162 static NsmErrorStatus_e NSM__enGetNodeState (NsmNodeState_e *penNodeState);
163 static NsmErrorStatus_e NSM__enGetApplicationMode(NsmApplicationMode_e *penApplicationMode);
166 /* Callbacks for D-Bus interfaces of the NodeStateManager */
167 static NsmErrorStatus_e NSM__enOnHandleSetBootMode (const gint i32BootMode);
168 static NsmErrorStatus_e NSM__enOnHandleSetNodeState (const NsmNodeState_e enNodeState);
169 static NsmErrorStatus_e NSM__enOnHandleSetApplicationMode (const NsmApplicationMode_e enApplMode);
170 static NsmErrorStatus_e NSM__enOnHandleRequestNodeRestart (const NsmRestartReason_e enRestartReason,
171 const guint u32RestartType);
172 static NsmErrorStatus_e NSM__enOnHandleSetAppHealthStatus (const gchar *sAppName,
173 const gboolean boAppState);
174 static gboolean NSM__boOnHandleCheckLucRequired (void);
175 static NsmErrorStatus_e NSM__enOnHandleRegisterSession (const gchar *sSessionName,
176 const gchar *sSessionOwner,
177 const NsmSeat_e enSeatId,
178 const NsmSessionState_e enSessionState);
179 static NsmErrorStatus_e NSM__enOnHandleUnRegisterSession (const gchar *sSessionName,
180 const gchar *sSessionOwner,
181 const NsmSeat_e enSeatId);
182 static NsmErrorStatus_e NSM__enOnHandleRegisterLifecycleClient (const gchar *sBusName,
183 const gchar *sObjName,
184 const guint u32ShutdownMode,
185 const guint u32TimeoutMs);
186 static NsmErrorStatus_e NSM__enOnHandleUnRegisterLifecycleClient(const gchar *sBusName,
187 const gchar *sObjName,
188 const guint u32ShutdownMode);
189 static NsmErrorStatus_e NSM__enOnHandleGetSessionState (const gchar *sSessionName,
190 const NsmSeat_e enSeatId,
191 NsmSessionState_e *penSessionState);
192 static NsmErrorStatus_e NSM__enOnHandleSetSessionState (const gchar *sSessionName,
193 const gchar *sSessionOwner,
194 const NsmSeat_e enSeatId,
195 const NsmSessionState_e enSessionState);
196 static guint NSM__u32OnHandleGetAppHealthCount (void);
197 static guint NSM__u32OnHandleGetInterfaceVersion (void);
199 /* Functions to simplify internal work flow */
200 static void NSM__vInitializeVariables (void);
201 static void NSM__vCreatePlatformSessions(void);
202 static void NSM__vCreateMutexes (void);
203 static void NSM__vDeleteMutexes (void);
205 /* LTPROF helper function */
206 static void NSM__vLtProf(gchar *pszBus, gchar *pszObj, guint32 dwReason, gchar *pszInOut, guint32 dwValue);
207 static void NSM__vSyslogOpen(void);
208 static void NSM__vSyslogClose(void);
211 /**********************************************************************************************************************
213 * Local variables and constants
215 **********************************************************************************************************************/
217 /* Context for Log'n'Trace */
218 DLT_DECLARE_CONTEXT(NsmContext);
220 /* Variables for "Properties" hosted by the NSM */
221 static GMutex *NSM__pSessionMutex = NULL;
222 static GSList *NSM__pSessions = NULL;
224 static GList *NSM__pLifecycleClients = NULL;
226 static GMutex *NSM__pNodeStateMutex = NULL;
227 static NsmNodeState_e NSM__enNodeState = NsmNodeState_NotSet;
229 static GMutex *NSM__pApplicationModeMutex = NULL;
230 static NsmApplicationMode_e NSM__enApplicationMode = NsmApplicationMode_NotSet;
232 static GSList *NSM__pFailedApplications = NULL;
234 /* Variables for internal state management (of lifecycle requests) */
235 static NSM__tstLifecycleClient *NSM__pCurrentLifecycleClient = NULL;
237 /* Constant array of callbacks which are registered at the NodeStateAccess library */
238 static const NSMA_tstObjectCallbacks NSM__stObjectCallBacks = { &NSM__enOnHandleSetBootMode,
239 &NSM__enOnHandleSetNodeState,
240 &NSM__enOnHandleSetApplicationMode,
241 &NSM__enOnHandleRequestNodeRestart,
242 &NSM__enOnHandleSetAppHealthStatus,
243 &NSM__boOnHandleCheckLucRequired,
244 &NSM__enOnHandleRegisterSession,
245 &NSM__enOnHandleUnRegisterSession,
246 &NSM__enOnHandleRegisterLifecycleClient,
247 &NSM__enOnHandleUnRegisterLifecycleClient,
248 &NSM__enGetApplicationMode,
249 &NSM__enOnHandleGetSessionState,
250 &NSM__enGetNodeState,
251 &NSM__enOnHandleSetSessionState,
252 &NSM__u32OnHandleGetAppHealthCount,
253 &NSM__u32OnHandleGetInterfaceVersion,
254 &NSM__vOnLifecycleRequestFinish
257 /**********************************************************************************************************************
259 * Local (static) functions
261 **********************************************************************************************************************/
264 /**********************************************************************************************************************
266 * This helper function is called from various places to check if a session is a "platform" session.
268 * @param pstSession: Pointer to the session for which a check should be done, if it is a platform session
270 * @return TRUE: The session is a "platform" session
271 * FALSE: The session is not a "platform" session
273 **********************************************************************************************************************/
274 static gboolean NSM__boIsPlatformSession(NsmSession_s *pstSession)
276 /* Function local variables */
277 gboolean boIsPlatformSession = FALSE;
278 guint16 u16SessionIdx = 0;
280 for(u16SessionIdx = 0;
281 (u16SessionIdx < sizeof(NSM__asDefaultSessions)/sizeof(gchar*))
282 && (boIsPlatformSession == FALSE);
285 boIsPlatformSession = (g_strcmp0(pstSession->sName, NSM__asDefaultSessions[u16SessionIdx]) == 0);
288 return boIsPlatformSession;
292 /**********************************************************************************************************************
294 * The function is called from IPC and StateMachine to set the NodeState.
296 * @param enNodeState: New NodeState that should be stored.
297 * @param boInformBus: Defines whether a D-Bus signal should be send when the NodeState could be changed.
298 * @param boInformMachine: Defines whether the StateMachine should be informed about the new NodeState.
300 * @return see NsmErrorStatus_e
302 **********************************************************************************************************************/
303 static NsmErrorStatus_e NSM__enSetNodeState(NsmNodeState_e enNodeState, gboolean boInformBus, gboolean boInformMachine)
305 /* Function local variables */
306 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
308 /* Check if the passed parameter is valid */
309 if((enNodeState > NsmNodeState_NotSet) && (enNodeState < NsmNodeState_Last))
311 /* Assert that the Node not already is shut down. Otherwise it will switch of immediately */
312 enRetVal = NsmErrorStatus_Ok;
314 g_mutex_lock(NSM__pNodeStateMutex);
316 /* Only store the new value and emit a signal, if the new value is different */
317 if(NSM__enNodeState != enNodeState)
319 /* Store the last NodeState, before switching to the new one */
320 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed NodeState." ),
321 DLT_STRING(" Old NodeState: "), DLT_INT((gint) NSM__enNodeState),
322 DLT_STRING(" New NodeState: "), DLT_INT((gint) enNodeState ));
325 /* Store the passed NodeState and emit a signal to inform system that the NodeState changed */
326 NSM__enNodeState = enNodeState;
328 /* If required, inform the D-Bus about the change (send signal) */
329 if(boInformBus == TRUE)
331 (void) NSMA_boSendNodeStateSignal(NSM__enNodeState);
334 /* If required, inform the StateMachine about the change */
335 if(boInformMachine == TRUE)
337 NsmcSetData(NsmDataType_NodeState, (unsigned char*) &NSM__enNodeState, sizeof(NsmDataType_NodeState));
340 /* Leave the lock now, because its not recursive. 'NSM__vCallNextLifecycleClient' may need it. */
341 g_mutex_unlock(NSM__pNodeStateMutex);
343 /* Check if a new life cycle request needs to be started based on the new ShutdownType */
344 if(NSM__pCurrentLifecycleClient == NULL)
346 NSM__vCallNextLifecycleClient();
351 /* NodeState stays the same. Just leave the lock. */
352 g_mutex_unlock(NSM__pNodeStateMutex);
357 /* Error: The passed boot mode is invalid. Return an error. */
358 enRetVal = NsmErrorStatus_Parameter;
359 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to change NodeState. Invalid parameter."),
360 DLT_STRING(" Old NodeState: "), DLT_INT(NSM__enNodeState ),
361 DLT_STRING(" Desired NodeState: "), DLT_INT((gint) enNodeState) );
368 /**********************************************************************************************************************
370 * The function is called from IPC and StateMachine to get the NodeState.
372 * @return see NsmNodeState_e
374 **********************************************************************************************************************/
375 static NsmErrorStatus_e NSM__enGetNodeState(NsmNodeState_e *penNodeState)
377 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
379 if(penNodeState != NULL)
381 enRetVal = NsmErrorStatus_Ok;
383 g_mutex_lock(NSM__pNodeStateMutex);
384 *penNodeState = NSM__enNodeState;
385 g_mutex_unlock(NSM__pNodeStateMutex);
389 enRetVal = NsmErrorStatus_Parameter;
396 /**********************************************************************************************************************
398 * The function is called from IPC and StateMachine to set the BootMode.
400 * @param i32BootMode: New BootMode that should be stored.
401 * @param boInformBus: Defines whether a D-Bus signal should be send when the BootMode could be changed.
402 * @param boInformMachine: Defines whether the StateMachine should be informed about the new BootMode.
404 * @return see NsmErrorStatus_e
406 **********************************************************************************************************************/
407 static NsmErrorStatus_e NSM__enSetBootMode(const gint i32BootMode, gboolean boInformMachine)
409 /* Function local variables */
410 gint i32CurrentBootMode = 0;
411 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
413 /* The BootMode property should be thread safe by D-Bus. No critical section need. */
414 (void) NSMA_boGetBootMode(&i32CurrentBootMode);
415 enRetVal = NsmErrorStatus_Ok;
417 if(i32CurrentBootMode != i32BootMode)
419 (void) NSMA_boSetBootMode(i32BootMode);
421 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed BootMode." ),
422 DLT_STRING(" Old BootMode: "), DLT_INT(i32CurrentBootMode),
423 DLT_STRING(" New BootMode: "), DLT_INT(i32BootMode ));
425 /* Inform the machine if desired. The D-Bus will auto. update, because this is property */
426 if(boInformMachine == TRUE)
428 NsmcSetData(NsmDataType_BootMode, (unsigned char*) &i32BootMode, sizeof(gint));
432 /* Return ok. There is no limitation for this value. */
436 /**********************************************************************************************************************
438 * The function is called from IPC and StateMachine to set the ApplicationMode.
440 * @param enApplicationMode: New application mode that should be stored.
441 * @param boInformBus: Defines whether a D-Bus signal should be send when the ApplicationMode could be changed.
442 * @param boInformMachine: Defines whether the StateMachine should be informed about the new ApplicationMode.
444 * @return see NsmErrorStatus_e
446 **********************************************************************************************************************/
447 static NsmErrorStatus_e NSM__enSetApplicationMode(NsmApplicationMode_e enApplicationMode, gboolean boInformBus, gboolean boInformMachine)
449 /* Function local variables */
450 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
452 /* Check if the passed parameter is valid */
453 if((enApplicationMode > NsmApplicationMode_NotSet) && (enApplicationMode < NsmApplicationMode_Last))
455 /* The passed parameter is valid. Return OK */
456 enRetVal = NsmErrorStatus_Ok;
458 g_mutex_lock(NSM__pApplicationModeMutex);
460 /* Only store the new value and emit a signal, if the new value is different */
461 if(NSM__enApplicationMode != enApplicationMode)
463 /* Store new value and emit signal with new application mode */
464 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed ApplicationMode."),
465 DLT_STRING(" Old ApplicationMode: "), DLT_INT(NSM__enApplicationMode ),
466 DLT_STRING(" New ApplicationMode: "), DLT_INT((gint) enApplicationMode));
468 NSM__enApplicationMode = enApplicationMode;
470 if(boInformBus == TRUE)
472 NSMA_boSendApplicationModeSignal(NSM__enApplicationMode);
475 if(boInformMachine == TRUE)
477 NsmcSetData(NsmDataType_AppMode, (unsigned char*) &NSM__enApplicationMode, sizeof(NsmApplicationMode_e));
481 g_mutex_unlock(NSM__pApplicationModeMutex);
485 /* Error: The passed application mode is invalid. Return an error. */
486 enRetVal = NsmErrorStatus_Parameter;
487 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to change ApplicationMode. Invalid parameter." ),
488 DLT_STRING(" Old ApplicationMode: "), DLT_INT(NSM__enApplicationMode ),
489 DLT_STRING(" Desired ApplicationMode: "), DLT_INT((gint) enApplicationMode));
496 /**********************************************************************************************************************
498 * The function is called from IPC and StateMachine to get the ApplicationMode.
500 * @return see NsmApplicationMode_e
502 **********************************************************************************************************************/
503 static NsmErrorStatus_e NSM__enGetApplicationMode(NsmApplicationMode_e *penApplicationMode)
505 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
507 if(penApplicationMode != NULL)
509 enRetVal = NsmErrorStatus_Ok;
510 g_mutex_lock(NSM__pApplicationModeMutex);
511 *penApplicationMode = NSM__enApplicationMode;
512 g_mutex_unlock(NSM__pApplicationModeMutex);
516 enRetVal = NsmErrorStatus_Parameter;
523 /**********************************************************************************************************************
525 * The function is called from the StateMachine. There is no D-Bus interface to set the ShutdownReason,
526 * because it is a property.
528 * @param enNewShutdownReason: New ShutdownReason that should be stored.
529 * @param boInformMachine: Determines if StateMachine needs to be called on a successful change.
530 * Most of the time this should be false, because the machine sets the
531 * value and can check the return value for errors.
533 * @return see NsmErrorStatus_e
535 **********************************************************************************************************************/
536 static NsmErrorStatus_e NSM__enSetShutdownReason(NsmShutdownReason_e enNewShutdownReason, gboolean boInformMachine)
538 /* Function local variables */
539 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
540 NsmShutdownReason_e enCurrentShutdownReason = NsmShutdownReason_NotSet;
542 /* Check if the passed parameter is valid */
543 if((enNewShutdownReason > NsmShutdownReason_NotSet) && (enNewShutdownReason < NsmShutdownReason_Last))
545 /* The passed parameter is valid. Return OK */
546 enRetVal = NsmErrorStatus_Ok;
547 (void) NSMA_boGetShutdownReason(&enCurrentShutdownReason);
549 /* Only store the new value and emit a signal, if the new value is different */
550 if(enNewShutdownReason != enCurrentShutdownReason)
552 /* Store new value and emit signal with new application mode */
553 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed ShutdownReason."),
554 DLT_STRING(" Old ShutdownReason: "), DLT_INT((gint) enCurrentShutdownReason),
555 DLT_STRING(" New ShutdownReason: "), DLT_INT((gint) enNewShutdownReason ));
557 (void) NSMA_boSetShutdownReason(enNewShutdownReason);
559 if(boInformMachine == TRUE)
561 NsmcSetData(NsmDataType_ShutdownReason, (unsigned char*) &enNewShutdownReason, sizeof(NsmShutdownReason_e));
567 /* Error: The passed application mode is invalid. Return an error. */
568 enRetVal = NsmErrorStatus_Parameter;
569 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to change ShutdownReason. Invalid parameter." ),
570 DLT_STRING(" Old ShutdownReason: "), DLT_INT((gint) enCurrentShutdownReason),
571 DLT_STRING(" Desired ShutdownReason: "), DLT_INT((gint) enNewShutdownReason ));
577 /**********************************************************************************************************************
579 * The function is called when a session state changed. It informs the system (IPC and StateMachine) about
580 * the changed session state.
582 * @param pstSession: Pointer to structure with updated session information.
583 * @param boInformBus: Defines whether a D-Bus signal should be send on session change.
584 * @param boInformMachine: Defines whether the StateMachine should be informed about session change.
586 **********************************************************************************************************************/
587 static void NSM__vPublishSessionChange(NsmSession_s *pstChangedSession, gboolean boInformBus, gboolean boInformMachine)
589 NsmErrorStatus_e enStateMachineReturn = NsmErrorStatus_NotSet;
591 if(boInformBus == TRUE)
593 NSMA_boSendSessionSignal(pstChangedSession);
596 if(boInformMachine == TRUE)
598 enStateMachineReturn = NsmcSetData(NsmDataType_SessionState, (unsigned char*) pstChangedSession, sizeof(NsmSession_s));
600 if(enStateMachineReturn != NsmErrorStatus_Ok)
602 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to inform state machine about changed session state." ),
603 DLT_STRING(" State machine returned: "), DLT_INT( enStateMachineReturn ),
604 DLT_STRING(" Application: "), DLT_STRING(pstChangedSession->sOwner ),
605 DLT_STRING(" Session: "), DLT_STRING(pstChangedSession->sName ),
606 DLT_STRING(" Seat: "), DLT_INT( pstChangedSession->enSeat ),
607 DLT_STRING(" Desired state: "), DLT_INT( pstChangedSession->enState));
613 /**********************************************************************************************************************
615 * The function is called when the state of a product session should be changed.
617 * @param pstSession: Pointer to structure where session name, owner, seat and desired SessionState are defined.
618 * @param boInformBus: Defines whether a D-Bus signal should be send on session change.
619 * @param boInformMachine: Defines whether the StateMachine should be informed about session change.
621 * @return see NsmErrorStatus_e
623 **********************************************************************************************************************/
624 static NsmErrorStatus_e NSM__enSetProductSessionState(NsmSession_s *pstSession, gboolean boInformBus, gboolean boInformMachine)
626 /* Function local variables */
627 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
628 GSList *pListEntry = NULL;
629 NsmSession_s *pExistingSession = NULL;
631 g_mutex_lock(NSM__pSessionMutex);
633 pListEntry = g_slist_find_custom(NSM__pSessions, pstSession, &NSM__i32SessionOwnerNameSeatCompare);
635 if(pListEntry != NULL)
637 enRetVal = NsmErrorStatus_Ok;
638 pExistingSession = (NsmSession_s*) pListEntry->data;
640 if(pExistingSession->enState != pstSession->enState)
642 pExistingSession->enState = pstSession->enState;
643 NSM__vPublishSessionChange(pExistingSession, boInformBus, boInformMachine);
648 enRetVal = NsmErrorStatus_WrongSession;
649 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set session state. Session unknown."),
650 DLT_STRING(" Application: "), DLT_STRING(pstSession->sOwner ),
651 DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ),
652 DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ),
653 DLT_STRING(" Desired state: "), DLT_INT( pstSession->enState));
656 g_mutex_unlock(NSM__pSessionMutex);
662 /**********************************************************************************************************************
664 * The function is called when the state of a default session should be changed.
666 * @param pstSession: Pointer to structure where session name, owner, seat and desired SessionState are defined.
667 * @param boInformBus: Defines whether a D-Bus signal should be send on session change.
668 * @param boInformMachine: Defines whether the StateMachine should be informed about session change.
670 * @return see NsmErrorStatus_e
672 **********************************************************************************************************************/
673 static NsmErrorStatus_e NSM__enSetDefaultSessionState(NsmSession_s *pstSession, gboolean boInformBus, gboolean boInformMachine)
675 /* Function local variables */
676 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
677 GSList *pListEntry = NULL;
678 NsmSession_s *pExistingSession = NULL;
680 /* Lock the sessions to be able to change them! */
681 g_mutex_lock(NSM__pSessionMutex);
683 pListEntry = g_slist_find_custom(NSM__pSessions, pstSession, &NSM__i32SessionNameSeatCompare);
685 if(pListEntry != NULL)
687 pExistingSession = (NsmSession_s*) pListEntry->data;
689 /* Check that the caller owns the session */
690 if(g_strcmp0(pExistingSession->sOwner, pstSession->sOwner) == 0)
692 enRetVal = NsmErrorStatus_Ok;
694 if(pExistingSession->enState != pstSession->enState)
696 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed default session's state."),
697 DLT_STRING(" Application: "), DLT_STRING(pExistingSession->sOwner ),
698 DLT_STRING(" Session: "), DLT_STRING(pExistingSession->sName ),
699 DLT_STRING(" Seat: "), DLT_INT( pExistingSession->enSeat ),
700 DLT_STRING(" Old state: "), DLT_INT( pExistingSession->enState),
701 DLT_STRING(" New state: "), DLT_INT( pstSession->enState ));
703 pExistingSession->enState = pstSession->enState;
705 NSM__vPublishSessionChange(pExistingSession, boInformBus, boInformMachine);
707 if(pstSession->enState == NsmSessionState_Inactive)
709 g_strlcpy(pExistingSession->sOwner, NSM_DEFAULT_SESSION_OWNER, sizeof(pExistingSession->sOwner));
715 /* The caller does not own the session. Check if he can become the owner. */
716 if(g_strcmp0(pExistingSession->sOwner, NSM_DEFAULT_SESSION_OWNER) == 0)
718 /* The session has no owner. The new owner can obtain the session by setting it to an "active" state */
719 if(pstSession->enState != NsmSessionState_Inactive)
721 /* The session has been activated. Overtake the owner. Broadcast new state. */
722 enRetVal = NsmErrorStatus_Ok;
723 g_strlcpy(pExistingSession->sOwner, pstSession->sOwner, sizeof(pExistingSession->sOwner));
725 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed default session's state."),
726 DLT_STRING(" Application: "), DLT_STRING(pExistingSession->sOwner ),
727 DLT_STRING(" Session: "), DLT_STRING(pExistingSession->sName ),
728 DLT_STRING(" Seat: "), DLT_INT( pExistingSession->enSeat ),
729 DLT_STRING(" Old state: "), DLT_INT( pExistingSession->enState),
730 DLT_STRING(" New state: "), DLT_INT( pstSession->enState ));
732 pExistingSession->enState = pstSession->enState;
734 NSM__vPublishSessionChange(pExistingSession, boInformBus, boInformMachine);
738 /* The session has no owner, but could not be activated because the passed state is "inactive". */
739 enRetVal = NsmErrorStatus_Parameter;
741 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to enable default session. Passed state is 'inactive'. "),
742 DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ),
743 DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ),
744 DLT_STRING(" Owning application: "), DLT_STRING(pExistingSession->sOwner ),
745 DLT_STRING(" Requesting application: "), DLT_STRING(pstSession->sOwner ));
750 /* The session owners do not match and the existing session has an owner */
751 enRetVal = NsmErrorStatus_Error;
753 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set default session state. Session has another owner."),
754 DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ),
755 DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ),
756 DLT_STRING(" Owning application: "), DLT_STRING(pExistingSession->sOwner ),
757 DLT_STRING(" Requesting application: "), DLT_STRING(pstSession->sOwner ));
763 /* This should never happen, because the function is only called for default sessions! */
764 enRetVal = NsmErrorStatus_Internal;
765 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Critical error. Default session not found in session list!"),
766 DLT_STRING(" Application: "), DLT_STRING(pstSession->sOwner ),
767 DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ),
768 DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ),
769 DLT_STRING(" Desired state: "), DLT_INT( pstSession->enState ));
772 /* Unlock the sessions again. */
773 g_mutex_unlock(NSM__pSessionMutex);
779 /**********************************************************************************************************************
781 * The function is called from IPC and StateMachine to set a session state.
783 * @param pstSession: Pointer to structure where session name, owner, seat and desired SessionState are defined.
784 * @param boInformBus: Defines whether a D-Bus signal should be send on session change.
785 * @param boInformMachine: Defines whether the StateMachine should be informed about session change.
787 * @return see NsmErrorStatus_e
789 **********************************************************************************************************************/
790 static NsmErrorStatus_e NSM__enSetSessionState(NsmSession_s *pstSession, gboolean boInformBus, gboolean boInformMachine)
792 /* Function local variables */
793 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
795 /* Check if the passed parameters are valid. */
796 if( (g_strcmp0(pstSession->sOwner, NSM_DEFAULT_SESSION_OWNER) != 0)
797 && (pstSession->enState > NsmSessionState_Unregistered )
798 && (pstSession->enSeat > NsmSeat_NotSet )
799 && (pstSession->enSeat < NsmSeat_Last ))
801 /* Parameters are valid. Check if a platform session state is set */
802 if(NSM__boIsPlatformSession(pstSession) == TRUE)
804 enRetVal = NSM__enSetDefaultSessionState(pstSession, boInformBus, boInformMachine);
808 enRetVal = NSM__enSetProductSessionState(pstSession, boInformBus, boInformMachine);
813 /* Error: An invalid parameter has been passed. */
814 enRetVal = NsmErrorStatus_Parameter;
815 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to change session state. Invalid paramter."),
816 DLT_STRING(" Application: "), DLT_STRING(pstSession->sOwner ),
817 DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ),
818 DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ),
819 DLT_STRING(" Desired state: "), DLT_INT( pstSession->enState ));
826 /**********************************************************************************************************************
828 * The function is called from IPC and StateMachine to get the session state.
830 * @param pstSession: Pointer to structure where session name, owner and seat are defined and SessionState will be set.
832 * @return see NsmErrorStatus_e
834 **********************************************************************************************************************/
835 static NsmErrorStatus_e NSM__enGetSessionState(NsmSession_s *pstSession)
837 /* Function local variables */
838 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
839 NsmSession_s *pExistingSession = NULL; /* Pointer to existing session */
840 GSList *pListEntry = NULL;
842 g_mutex_lock(NSM__pSessionMutex);
844 /* Search for session with name, seat and owner. */
845 pListEntry = g_slist_find_custom(NSM__pSessions, pstSession, &NSM__i32SessionNameSeatCompare);
847 if(pListEntry != NULL)
849 /* Found the session in the list. Return its state. */
850 enRetVal = NsmErrorStatus_Ok;
851 pExistingSession = (NsmSession_s*) pListEntry->data;
852 pstSession->enState = pExistingSession->enState;
856 /* Error: The session is unknown. */
857 enRetVal = NsmErrorStatus_WrongSession;
858 DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to retrieve session state. Unknown session."),
859 DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ),
860 DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ));
863 g_mutex_unlock(NSM__pSessionMutex);
869 static void NSM__vFreeFailedApplicationObject(gpointer pFailedApplication)
871 /* Function local variables. Cast the passed object */
872 NSM__tstFailedApplication *pstFailedApplication = (NSM__tstFailedApplication*) pFailedApplication;
874 g_free(pstFailedApplication);
878 /**********************************************************************************************************************
880 * The function is called either manually for one object or for every "session object", when the list of registered
881 * sessions is destroyed with "g_slist_free_full". All memory occupied by the "session object" is released.
883 * @param pSession: Pointer to the session object
887 **********************************************************************************************************************/
888 static void NSM__vFreeSessionObject(gpointer pSession)
890 /* Function local variables. Cast the passed object */
891 NsmSession_s *pstSession = (NsmSession_s*) pSession;
893 /* Free the session object */
898 /**********************************************************************************************************************
900 * The function is called either manually for one object or for every "lifecycle client object", when the list of
901 * registered lifecycle clients is destroyed with "g_slist_free_full".
902 * All memory occupied by the "lifecycle client object" is released.
904 * @param pLifecycleClient: Pointer to the lifecycle client object
908 **********************************************************************************************************************/
909 static void NSM__vFreeLifecycleClientObject(gpointer pLifecycleClient)
911 /* Function local variables. Cast the passed object */
912 NSM__tstLifecycleClient *pstLifecycleClient = (NSM__tstLifecycleClient*) pLifecycleClient;
914 /* Free internal strings and objects */
915 g_free(pstLifecycleClient->sBusName);
916 g_free(pstLifecycleClient->sObjName);
918 /* No need to check for NULL. Only valid clients come here */
919 NSMA_boFreeLcConsumerProxy(pstLifecycleClient->hClient);
921 /* Free the shutdown client object */
922 g_free(pstLifecycleClient);
926 /**********************************************************************************************************************
928 * The function is used to "custom compare" and identify a lifecycle client in the list of clients.
929 * Because the function is not used for sorting, the return value 1 is not used.
931 * @param pS1: Lifecycle client from list
932 * @param pS2: Lifecycle client to compare
934 * @return -1: pL1 < pL2
936 * 1: pL1 > pL2 (unused, because function not used for sorting)
938 **********************************************************************************************************************/
939 static gint NSM__i32LifecycleClientCompare(gconstpointer pL1, gconstpointer pL2)
941 /* Function local variables. Cast the passed objects */
942 NSM__tstLifecycleClient *pListClient = NULL;
943 NSM__tstLifecycleClient *pCompareClient = NULL;
946 pListClient = (NSM__tstLifecycleClient*) pL1;
947 pCompareClient = (NSM__tstLifecycleClient*) pL2;
949 /* Compare the bus name of the client */
950 if(g_strcmp0(pListClient->sBusName, pCompareClient->sBusName) == 0)
952 /* Bus names are equal. Now compare object name */
953 if(g_strcmp0(pListClient->sObjName, pCompareClient->sObjName) == 0)
955 i32RetVal = 0; /* Clients are identical. Return 0. */
959 i32RetVal = -1; /* Object names are different. Return -1. */
964 i32RetVal = -1; /* Bus names are different. Return -1. */
967 return i32RetVal; /* Return result of comparison. */
971 /**********************************************************************************************************************
973 * The function is used to "custom compare" and identify a session in the list of sessions.
974 * It compares the "session name", the "session owner" and "seat".
975 * Because the function is not used for sorting, the return value 1 is not used.
977 * @param pS1: Session from list
978 * @param pS2: Session to compare
980 * @return -1: pS1 < pS2
982 * 1: pS1 > pS2 (unused, because function not used for sorting)
984 **********************************************************************************************************************/
985 static gint NSM__i32SessionOwnerNameSeatCompare(gconstpointer pS1, gconstpointer pS2)
987 /* Function local variables. Cast the passed objects */
988 NsmSession_s *pListSession = NULL;
989 NsmSession_s *pSearchSession = NULL;
992 pListSession = (NsmSession_s*) pS1;
993 pSearchSession = (NsmSession_s*) pS2;
995 if(g_strcmp0(pListSession->sOwner, pSearchSession->sOwner) == 0)
997 i32RetVal = NSM__i32SessionNameSeatCompare(pS1, pS2);
1001 i32RetVal = -1; /* Session owners differ. Return -1. */
1004 return i32RetVal; /* Return result of comparison */
1008 /**********************************************************************************************************************
1010 * The function is used to "custom compare" and identify a session in the list of sessions.
1011 * It compares the "session name" and "seat".
1012 * Because the function is not used for sorting, the return value 1 is not used.
1014 * @param pS1: Session from list
1015 * @param pS2: Session to compare
1017 * @return -1: pS1 < pS2
1019 * 1: pS1 > pS2 (unused, because function not used for sorting)
1021 **********************************************************************************************************************/
1022 static gint NSM__i32SessionNameSeatCompare(gconstpointer pS1, gconstpointer pS2)
1024 /* Function local variables. Cast the passed objects */
1025 NsmSession_s *pListSession = NULL;
1026 NsmSession_s *pSearchSession = NULL;
1029 pListSession = (NsmSession_s*) pS1;
1030 pSearchSession = (NsmSession_s*) pS2;
1032 /* Compare seats of the sessions. */
1033 if(pListSession->enSeat == pSearchSession->enSeat)
1035 /* Seats are equal. Compare session names. */
1036 if(g_strcmp0(pListSession->sName, pSearchSession->sName) == 0)
1038 i32RetVal = 0; /* Session are equal. Return 0. */
1042 i32RetVal = -1; /* Session names differ. Return -1. */
1047 i32RetVal = -1; /* Session seats differ. Return -1. */
1054 /**********************************************************************************************************************
1056 * The function is used to "custom compare" and identify an application name.
1057 * Because the function is not used for sorting, the return value 1 is not used.
1059 * @param pA1: Application object from list
1060 * @param pA2: Application object to compare
1062 * @return -1: pA1 < pA2
1064 * 1: pA1 > pA2 (unused, because function not used for sorting)
1066 **********************************************************************************************************************/
1067 static gint NSM__i32ApplicationCompare(gconstpointer pA1, gconstpointer pA2)
1069 /* Function local variables. Cast the passed objects */
1070 NSM__tstFailedApplication *pListApp = NULL;
1071 NSM__tstFailedApplication *pSearchApp = NULL;
1074 pListApp = (NSM__tstFailedApplication*) pA1;
1075 pSearchApp = (NSM__tstFailedApplication*) pA2;
1077 /* Compare names of the applications */
1078 if(g_strcmp0(pListApp->sName, pSearchApp->sName) == 0)
1080 i32RetVal = 0; /* Names are equal. Return 0. */
1084 i32RetVal = -1; /* Names are different. Return -1. */
1087 return i32RetVal; /* Return result of comparison */
1091 /**********************************************************************************************************************
1093 * The function is used to "custom compare" and identify a session with a special owner.
1094 * Because the function is not used for sorting, the return value 1 is not used.
1096 * @param pS1: Session from list
1097 * @param pS2: Session to compare
1099 * @return -1: pS1 < pS2
1101 * 1: pS1 > pS2 (unused, because function not used for sorting)
1103 **********************************************************************************************************************/
1104 static gint NSM__i32SessionOwnerCompare(gconstpointer pS1, gconstpointer pS2)
1106 /* Function local variables. Cast the passed objects */
1107 NsmSession_s *pListSession = NULL;
1108 NsmSession_s *pSearchSession = NULL;
1111 pListSession = (NsmSession_s*) pS1;
1112 pSearchSession = (NsmSession_s*) pS2;
1114 /* Compare owners of the sessions */
1115 if(g_strcmp0(pListSession->sOwner, pSearchSession->sOwner) == 0)
1117 i32RetVal = 0; /* Owners are equal. Return 0. */
1121 i32RetVal = -1; /* Owners are different. Return -1. */
1124 return i32RetVal; /* Return result of comparison */
1128 /**********************************************************************************************************************
1130 * The function is called after a lifecycle client was informed about the changed life cycle.
1131 * The return value of the last informed client will be evaluated and the next lifecycle client
1132 * to inform will be determined and called.
1133 * If there is no client left, the lifecycle sequence will be finished.
1135 * @param pSrcObject: Source object (lifecycle client proxy)
1136 * @param pRes: Result of asynchronous call
1137 * @param pUserData: Pointer to the current lifecycle client object
1141 **********************************************************************************************************************/
1142 static void NSM__vOnLifecycleRequestFinish(const NsmErrorStatus_e enErrorStatus)
1144 if(enErrorStatus == NsmErrorStatus_Ok)
1146 /* The clients "LifecycleRequest" has been successfully processed. */
1147 NSM__vLtProf(NSM__pCurrentLifecycleClient->sBusName, NSM__pCurrentLifecycleClient->sObjName, 0, "leave: ", 0);
1148 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Successfully called lifecycle client."));
1152 /* Error: The method of the lifecycle client returned an error */
1153 NSM__vLtProf(NSM__pCurrentLifecycleClient->sBusName, NSM__pCurrentLifecycleClient->sObjName, 0, "leave: error: ", enErrorStatus);
1154 DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to call life cycle client." ),
1155 DLT_STRING(" Return Value: "), DLT_INT((gint) enErrorStatus));
1158 NSM__vCallNextLifecycleClient();
1162 /**********************************************************************************************************************
1164 * The function is called when:
1165 * - The NodeState changes (NSM__boHandleSetNodeState), to initiate a lifecycle sequence
1166 * - A client returned and the next client has to be called (NSM__vOnLifecycleRequestFinish)
1168 * If the clients need to "run up" or shut down for the current NodeState, the function
1169 * searches the list forward or backward until a client is found, which needs to be informed.
1171 * PLEASE NOTE: If all clients have been informed about a "shut down", this function will quit the
1172 * "g_main_loop", which leads to the the termination of the NSM!
1176 **********************************************************************************************************************/
1177 static void NSM__vCallNextLifecycleClient(void)
1179 /* Function local variables */
1180 GList *pListEntry = NULL; /* Iterate through list entries */
1181 NSM__tstLifecycleClient *pClient = NULL; /* Client object from list */
1182 guint32 u32ShutdownType = NSM_SHUTDOWNTYPE_NOT; /* Return value */
1183 gboolean boShutdown = FALSE;
1185 NSM__pCurrentLifecycleClient = NULL;
1187 g_mutex_lock(NSM__pNodeStateMutex);
1189 /* Based on NodeState determine if clients have to shutdown or run up. Find a client that has not been informed */
1190 switch(NSM__enNodeState)
1192 /* For "shutdown" search backward in the list, until there is a client that has not been shut down */
1193 case NsmNodeState_ShuttingDown:
1194 u32ShutdownType = NSM_SHUTDOWNTYPE_NORMAL;
1195 for( pListEntry = g_list_last(NSM__pLifecycleClients);
1196 (pListEntry != NULL) && (NSM__pCurrentLifecycleClient == NULL);
1197 pListEntry = g_list_previous(pListEntry))
1199 /* Check if client has not been shut down and is registered for "normal shutdown" */
1200 pClient = (NSM__tstLifecycleClient*) pListEntry->data;
1201 if( ( pClient->boShutdown == FALSE)
1202 && ( (pClient->u32RegisteredMode & u32ShutdownType) != 0 ))
1204 /* Found a "running" previous client, registered for the shutdown mode */
1205 NSM__pCurrentLifecycleClient = (NSM__tstLifecycleClient*) pListEntry->data;
1210 /* For "fast shutdown" search backward in the list, until there is a client that has not been shut down */
1211 case NsmNodeState_FastShutdown:
1212 u32ShutdownType = NSM_SHUTDOWNTYPE_FAST;
1213 for( pListEntry = g_list_last(NSM__pLifecycleClients);
1214 (pListEntry != NULL) && (NSM__pCurrentLifecycleClient == NULL);
1215 pListEntry = g_list_previous(pListEntry))
1217 /* Check if client has not been shut down and is registered for "fast shutdown" */
1218 pClient = (NSM__tstLifecycleClient*) pListEntry->data;
1219 if( ( pClient->boShutdown == FALSE)
1220 && ( (pClient->u32RegisteredMode & u32ShutdownType) != 0 ))
1222 /* Found a "running" previous client, registered for the shutdown mode */
1223 NSM__pCurrentLifecycleClient = (NSM__tstLifecycleClient*) pListEntry->data;
1228 /* For a "running" mode search forward in the list (get next), until there is a client that is shut down */
1230 u32ShutdownType = NSM_SHUTDOWNTYPE_RUNUP;
1231 for(pListEntry = g_list_first(NSM__pLifecycleClients);
1232 (pListEntry != NULL) && (NSM__pCurrentLifecycleClient == NULL);
1233 pListEntry = g_list_next(pListEntry))
1235 /* Check if client is shut down */
1236 pClient = (NSM__tstLifecycleClient*) pListEntry->data;
1237 if(pClient->boShutdown == TRUE)
1239 /* The client was shutdown. It should run up, because we are in a running mode */
1240 NSM__pCurrentLifecycleClient = (NSM__tstLifecycleClient*) pListEntry->data;
1246 /* Check if a client could be found that needs to be informed */
1247 if(NSM__pCurrentLifecycleClient != NULL)
1249 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Call lifecycle client." ),
1250 DLT_STRING(" Bus name: "), DLT_STRING(NSM__pCurrentLifecycleClient->sBusName ),
1251 DLT_STRING(" Obj name: "), DLT_STRING(NSM__pCurrentLifecycleClient->sObjName ),
1252 DLT_STRING(" Registered types: "), DLT_INT(NSM__pCurrentLifecycleClient->u32RegisteredMode),
1253 DLT_STRING(" Client: "), DLT_INT( (guint) NSM__pCurrentLifecycleClient->hClient ),
1254 DLT_STRING(" ShutdownType: "), DLT_UINT(u32ShutdownType ));
1256 /* Remember that client received a run-up or shutdown call */
1257 pClient->boShutdown = (u32ShutdownType != NSM_SHUTDOWNTYPE_RUNUP);
1259 NSM__vLtProf(NSM__pCurrentLifecycleClient->sBusName, NSM__pCurrentLifecycleClient->sObjName, u32ShutdownType, "enter: ", 0);
1261 NSMA_boCallLcClientRequest(NSM__pCurrentLifecycleClient->hClient, u32ShutdownType);
1266 /* The last client was called. Depending on the NodeState check if we can end. */
1267 switch(NSM__enNodeState)
1269 /* All registered clients have been 'fast shutdown'. Set NodeState to "shutdown" */
1270 case NsmNodeState_FastShutdown:
1271 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Informed all registered clients about 'fast shutdown'. Set NodeState to 'shutdown'"));
1273 NSM__enNodeState = NsmNodeState_Shutdown;
1274 NsmcSetData(NsmDataType_NodeState, (unsigned char*) &NSM__enNodeState, sizeof(NsmNodeState_e));
1275 NSMA_boSendNodeStateSignal(NSM__enNodeState);
1279 /* All registered clients have been 'shutdown'. Set NodeState to "shutdown" */
1280 case NsmNodeState_ShuttingDown:
1281 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Informed all registered clients about 'shutdown'. Set NodeState to 'shutdown'."));
1283 NSM__enNodeState = NsmNodeState_Shutdown;
1284 NsmcSetData(NsmDataType_NodeState, (unsigned char*) &NSM__enNodeState, sizeof(NsmNodeState_e));
1285 NSMA_boSendNodeStateSignal(NSM__enNodeState);
1289 /* We are in a running state. Nothing to do */
1296 g_mutex_unlock(NSM__pNodeStateMutex);
1298 if(boShutdown == TRUE)
1300 NSMA_boQuitEventLoop();
1305 /**********************************************************************************************************************
1307 * The callback is called when a check for LUC is required.
1308 * It uses the NodeStateMachine to determine whether LUC is required.
1310 * @param pboRetVal: Pointer, where to store the StateMAchine's return value
1312 **********************************************************************************************************************/
1313 static gboolean NSM__boOnHandleCheckLucRequired(void)
1315 /* Determine if LUC is required by asking the NodeStateMachine */
1316 return (NsmcLucRequired() == 0x01) ? TRUE : FALSE;
1320 /**********************************************************************************************************************
1322 * The callback is called when the "boot mode" should be set.
1323 * It sets the BootMode using an internal function.
1325 * @param i32BootMode: New boot mode
1326 * @param penRetVal: Pointer, where to store the return value
1328 **********************************************************************************************************************/
1329 static NsmErrorStatus_e NSM__enOnHandleSetBootMode(const gint i32BootMode)
1331 /* Use internal setter to set the BootMode and inform the StateMachine */
1332 return NSM__enSetBootMode(i32BootMode, TRUE);
1336 /**********************************************************************************************************************
1338 * The callback is called when the "node state" should be set.
1339 * It sets the NodeState using an internal function.
1341 * @param enNodeStateId: New node state
1342 * @param penRetVal: Pointer, where to store the return value
1344 **********************************************************************************************************************/
1345 static NsmErrorStatus_e NSM__enOnHandleSetNodeState(const NsmNodeState_e enNodeState)
1347 return NSM__enSetNodeState(enNodeState, TRUE, TRUE);
1351 /**********************************************************************************************************************
1353 * The callback is called when the "application mode" should be set.
1354 * It sets the ApplicationMode using an internal function.
1356 * @param enApplicationModeId: New application mode
1357 * @param penRetVal: Pointer, where to store the return value
1359 **********************************************************************************************************************/
1360 static NsmErrorStatus_e NSM__enOnHandleSetApplicationMode(const NsmApplicationMode_e enApplMode)
1362 return NSM__enSetApplicationMode(enApplMode, TRUE, TRUE);
1366 /**********************************************************************************************************************
1368 * The callback is called when the node reset is requested.
1369 * It passes the request to the NodestateMachine.
1371 * @param i32RestartReason: Restart reason
1372 * @param i32RestartType: Restart type
1373 * @param penRetVal: Pointer, where to store the return value
1375 **********************************************************************************************************************/
1376 static NsmErrorStatus_e NSM__enOnHandleRequestNodeRestart(const NsmRestartReason_e enRestartReason,
1377 const guint u32RestartType)
1379 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
1381 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Node restart has been requested."));
1383 if(NsmcRequestNodeRestart() == 0x01)
1385 enRetVal = NsmErrorStatus_Ok;
1386 (void) NSMA_boSetRestartReason(enRestartReason);
1390 enRetVal = NsmErrorStatus_Error;
1397 /**********************************************************************************************************************
1399 * The called is called when a new session should be registered.
1400 * It checks the passed parameters and creates a NsmSession_s structure of them.
1401 * If everything is ok, the new session will be created and the system and StateMachine will be informed.
1403 * @param sSessionName: Name of the new session
1404 * @param sSessionOwner: Owner of the new session
1405 * @param enSeatId: Seat which belongs to the new session
1406 * @param enSessionState: Initial state of the new session
1407 * @param penRetVal: Pointer, where to store the return value
1409 **********************************************************************************************************************/
1410 static NsmErrorStatus_e NSM__enOnHandleRegisterSession(const gchar *sSessionName,
1411 const gchar *sSessionOwner,
1412 const NsmSeat_e enSeatId,
1413 const NsmSessionState_e enSessionState)
1415 /* Function local variables */
1416 NsmSession_s *pNewSession = NULL; /* Pointer to new created session */
1417 GSList *pListEntry = NULL; /* Pointer to list entry */
1418 glong u32SessionNameLen = 0; /* Length of passed session owner */
1419 glong u32SessionOwnerLen = 0; /* Length of passed session name */
1420 NsmSession_s stSearchSession = {0}; /* To search for existing session */
1421 gboolean boOwnerValid = FALSE;
1422 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
1424 /* Check if the passed parameters are valid */
1425 u32SessionNameLen = g_utf8_strlen(sSessionName, -1);
1426 u32SessionOwnerLen = g_utf8_strlen(sSessionOwner, -1);
1427 boOwnerValid = (g_strcmp0(sSessionOwner, NSM_DEFAULT_SESSION_OWNER) != 0);
1429 if( (boOwnerValid == TRUE )
1430 && (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH )
1431 && (u32SessionOwnerLen < NSM_MAX_SESSION_OWNER_LENGTH)
1432 && (enSeatId > NsmSeat_NotSet )
1433 && (enSeatId < NsmSeat_Last )
1434 && (enSessionState > NsmSessionState_Unregistered))
1436 /* Initialize temporary session object to check if session already exists */
1437 g_strlcpy((gchar*) stSearchSession.sName, sSessionName, sizeof(stSearchSession.sName) );
1438 g_strlcpy((gchar*) stSearchSession.sOwner, sSessionOwner, sizeof(stSearchSession.sOwner));
1439 stSearchSession.enSeat = enSeatId;
1440 stSearchSession.enState = enSessionState;
1442 if(NSM__boIsPlatformSession(&stSearchSession) == FALSE)
1444 g_mutex_lock(NSM__pSessionMutex);
1446 pListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionNameSeatCompare);
1448 if(pListEntry == NULL)
1450 enRetVal = NsmErrorStatus_Ok;
1452 pNewSession = g_new0(NsmSession_s, 1);
1453 memcpy(pNewSession, &stSearchSession, sizeof(NsmSession_s));
1455 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Registered session." ),
1456 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1457 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1458 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
1459 DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState));
1461 /* Return OK and append new object */
1462 NSM__pSessions = g_slist_append(NSM__pSessions, pNewSession);
1464 /* Inform D-Bus and StateMachine about the new session. */
1465 NSM__vPublishSessionChange(pNewSession, TRUE, TRUE);
1469 /* Error: The session already exists. Don't store passed state. */
1470 enRetVal = NsmErrorStatus_WrongSession;
1471 DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to register session. Session already exists."),
1472 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1473 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1474 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
1475 DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState ));
1478 g_mutex_unlock(NSM__pSessionMutex);
1482 /* Error: It is not allowed to re-register a default session! */
1483 enRetVal = NsmErrorStatus_Parameter;
1484 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to register session. Re-Registration of default session not allowed."),
1485 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1486 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1487 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
1488 DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState ));
1493 /* Error: A parameter with an invalid value has been passed */
1494 enRetVal = NsmErrorStatus_Parameter;
1495 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to register session. 'Unregistered' not allowed."),
1496 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1497 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1498 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
1499 DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState ));
1506 /**********************************************************************************************************************
1508 * The callback is called when a session should be unregistered.
1509 * It checks the passed parameters and creates a NsmSession_s structure of them.
1510 * If everything is ok, the new session will be removed and the system and StateMachine will be informed.
1512 * @param sSessionName: Name of the new session that should be unregistered.
1513 * @param sSessionOwner: Current owner of the session that should be unregistered.
1514 * @param enSeat: Seat for which the session should be unregistered.
1515 * @param penRetVal: Pointer, where to store the return value
1517 **********************************************************************************************************************/
1518 static NsmErrorStatus_e NSM__enOnHandleUnRegisterSession(const gchar *sSessionName,
1519 const gchar *sSessionOwner,
1520 const NsmSeat_e enSeatId)
1522 /* Function local variables */
1523 NsmSession_s *pExistingSession = NULL; /* Pointer to existing session */
1524 GSList *pListEntry = NULL; /* Pointer to list entry */
1525 glong u32SessionNameLen = 0; /* Length of passed session owner */
1526 glong u32SessionOwnerLen = 0; /* Length of passed session name */
1527 NsmSession_s stSearchSession = {0}; /* To search for existing session */
1528 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
1530 /* Check if the passed parameters are valid */
1531 u32SessionNameLen = g_utf8_strlen(sSessionName, -1);
1532 u32SessionOwnerLen = g_utf8_strlen(sSessionOwner, -1);
1534 if( (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH )
1535 && (u32SessionOwnerLen < NSM_MAX_SESSION_OWNER_LENGTH))
1537 /* Assign seat, session name and owner to search for session */
1538 stSearchSession.enSeat = enSeatId;
1539 g_strlcpy((gchar*) stSearchSession.sName, sSessionName, sizeof(stSearchSession.sName) );
1540 g_strlcpy((gchar*) stSearchSession.sOwner, sSessionOwner, sizeof(stSearchSession.sOwner));
1542 if(NSM__boIsPlatformSession(&stSearchSession) == FALSE)
1544 g_mutex_lock(NSM__pSessionMutex);
1546 pListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionOwnerNameSeatCompare);
1548 /* Check if the session exists */
1549 if(pListEntry != NULL)
1551 /* Found the session in the list. Now remove it. */
1552 enRetVal = NsmErrorStatus_Ok;
1553 pExistingSession = (NsmSession_s*) pListEntry->data;
1555 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Unregistered session." ),
1556 DLT_STRING(" Name: " ), DLT_STRING(pExistingSession->sName ),
1557 DLT_STRING(" Owner: " ), DLT_STRING(pExistingSession->sOwner ),
1558 DLT_STRING(" Seat: " ), DLT_INT( pExistingSession->enSeat ),
1559 DLT_STRING(" Last state: "), DLT_INT( pExistingSession->enState));
1561 pExistingSession->enState = NsmSessionState_Unregistered;
1563 /* Inform D-Bus and StateMachine about the unregistered session */
1564 NSM__vPublishSessionChange(pExistingSession, TRUE, TRUE);
1566 NSM__vFreeSessionObject(pExistingSession);
1567 NSM__pSessions = g_slist_remove(NSM__pSessions, pExistingSession);
1571 /* Error: The session is unknown. */
1572 enRetVal = NsmErrorStatus_WrongSession;
1573 DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to unregister session. Session unknown."),
1574 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1575 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1576 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ));
1579 g_mutex_unlock(NSM__pSessionMutex);
1583 /* Error: Failed to unregister session. The passed session is a "platform" session. */
1584 enRetVal = NsmErrorStatus_WrongSession;
1585 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to unregister session. The session is a platform session."),
1586 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1587 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1588 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ));
1593 /* Error: Invalid parameter. The session or owner name is to long. */
1594 enRetVal = NsmErrorStatus_Parameter;
1595 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to unregister session. The session or owner name is to long."),
1596 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1597 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1598 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ));
1605 /**********************************************************************************************************************
1607 * The callback is called when a lifecycle client should be registered.
1608 * In the list of lifecycle clients it will be checked if the client already exists.
1609 * If it exists, it's settings will be updated. Otherwise a new client will be created.
1611 * @param sBusName: Bus name of the remote application that hosts the lifecycle client interface
1612 * @param sObjName: Object name of the lifecycle client
1613 * @param u32ShutdownMode: Shutdown mode for which the client wants to be informed
1614 * @param u32TimeoutMs: Timeout in ms. If the client does not return after the specified time, the NSM
1615 * aborts its shutdown and calls the next client.
1616 * @param penRetVal: Pointer, where to store the return value
1618 **********************************************************************************************************************/
1619 static NsmErrorStatus_e NSM__enOnHandleRegisterLifecycleClient(const gchar *sBusName,
1620 const gchar *sObjName,
1621 const guint u32ShutdownMode,
1622 const guint u32TimeoutMs)
1624 NSM__tstLifecycleClient stTestLifecycleClient = {0};
1625 NSM__tstLifecycleClient *pstNewClient = NULL;
1626 NSM__tstLifecycleClient *pstExistingClient = NULL;
1627 GList *pListEntry = NULL;
1628 NSMA_tLcConsumerHandle *hConsumer = NULL;
1629 GError *pError = NULL;
1630 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
1632 /* The parameters are valid. Create a temporary client to search the list */
1633 stTestLifecycleClient.sBusName = (gchar*) sBusName;
1634 stTestLifecycleClient.sObjName = (gchar*) sObjName;
1636 /* Check if the lifecycle client already is registered */
1637 pListEntry = g_list_find_custom(NSM__pLifecycleClients, &stTestLifecycleClient, &NSM__i32LifecycleClientCompare);
1639 if(pListEntry == NULL)
1641 /* The client does not exist. Try to create a new proxy */
1642 hConsumer = NSMA_hCreateLcConsumer(sBusName, sObjName, u32TimeoutMs);
1644 /* The new proxy could be created. Create and store new client */
1645 if(hConsumer != NULL)
1647 enRetVal = NsmErrorStatus_Ok;
1649 /* Create client object and copies of the strings. */
1650 pstNewClient = g_new0(NSM__tstLifecycleClient, 1);
1651 pstNewClient->u32RegisteredMode = u32ShutdownMode;
1652 pstNewClient->sBusName = g_strdup(sBusName);
1653 pstNewClient->sObjName = g_strdup(sObjName);
1654 pstNewClient->boShutdown = FALSE;
1655 pstNewClient->hClient = hConsumer;
1658 /* Append the new client to the list */
1659 NSM__pLifecycleClients = g_list_append(NSM__pLifecycleClients, pstNewClient);
1661 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Registered new lifecycle consumer." ),
1662 DLT_STRING(" Bus name: "), DLT_STRING(pstNewClient->sBusName ),
1663 DLT_STRING(" Obj name: "), DLT_STRING(pstNewClient->sObjName ),
1664 DLT_STRING(" Timeout: " ), DLT_UINT( u32TimeoutMs ),
1665 DLT_STRING(" Mode(s): "), DLT_INT( pstNewClient->u32RegisteredMode),
1666 DLT_STRING(" Client: "), DLT_UINT((guint) pstNewClient->hClient ));
1670 enRetVal = NsmErrorStatus_Dbus;
1671 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Failed to register new lifecycle consumer. D-Bus error."),
1672 DLT_STRING(" Bus name: "), DLT_STRING(sBusName ),
1673 DLT_STRING(" Obj name: "), DLT_STRING(sObjName ),
1674 DLT_STRING(" Timeout: " ), DLT_UINT( u32TimeoutMs ),
1675 DLT_STRING(" Registered mode(s): "), DLT_INT( u32ShutdownMode ),
1676 DLT_STRING(" Error: "), DLT_STRING(pError->message ));
1678 g_error_free(pError);
1683 /* The client already exists. Assert to update the values for timeout and mode */
1684 enRetVal = NsmErrorStatus_Ok;
1685 pstExistingClient = (NSM__tstLifecycleClient*) pListEntry->data;
1686 pstExistingClient->u32RegisteredMode |= u32ShutdownMode;
1687 NSMA_boSetLcClientTimeout(pstExistingClient->hClient, u32TimeoutMs);
1689 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed lifecycle consumer registration." ),
1690 DLT_STRING(" Bus name: "), DLT_STRING(pstExistingClient->sBusName ),
1691 DLT_STRING(" Obj name: "), DLT_STRING(pstExistingClient->sObjName ),
1692 DLT_STRING(" Timeout: " ), DLT_UINT( u32TimeoutMs ),
1693 DLT_STRING(" Registered mode(s): "), DLT_INT( pstExistingClient->u32RegisteredMode));
1700 /**********************************************************************************************************************
1702 * The callback is called when a lifecycle client should be unregistered or a shutdown
1703 * mode should be removed. In the list of lifecycle clients will be checked if the client exists. If the
1704 * client is found, the registration for the passed shutdown modes will be removed. If the client finally
1705 * is not registered for any shutdown mode, its entry will be removed from the list.
1707 * @param sBusName: Bus name of the remote application that hosts the lifecycle client interface
1708 * @param sObjName: Object name of the lifecycle client
1709 * @param u32ShutdownMode: Shutdown mode for which the client wants to unregister
1710 * @param penRetVal: Pointer, where to store the return value
1712 **********************************************************************************************************************/
1713 static NsmErrorStatus_e NSM__enOnHandleUnRegisterLifecycleClient(const gchar *sBusName,
1714 const gchar *sObjName,
1715 const guint u32ShutdownMode)
1717 NSM__tstLifecycleClient *pstExistingClient = NULL;
1718 NSM__tstLifecycleClient stSearchClient = {0};
1719 GList *pListEntry = NULL;
1720 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
1722 stSearchClient.sBusName = (gchar*) sBusName;
1723 stSearchClient.sObjName = (gchar*) sObjName;
1725 /* Check if the lifecycle client already is registered */
1726 pListEntry = g_list_find_custom(NSM__pLifecycleClients, &stSearchClient, &NSM__i32LifecycleClientCompare);
1728 /* Check if an existing client could be found */
1729 if(pListEntry != NULL)
1731 /* The client could be found in the list. Change the registered shutdown mode */
1732 enRetVal = NsmErrorStatus_Ok;
1733 pstExistingClient = (NSM__tstLifecycleClient*) pListEntry->data;
1734 pstExistingClient->u32RegisteredMode &= ~(u32ShutdownMode);
1736 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Unregistered lifecycle consumer for mode(s)." ),
1737 DLT_STRING(" Bus name: "), DLT_STRING(pstExistingClient->sBusName ),
1738 DLT_STRING(" Obj name: "), DLT_STRING(pstExistingClient->sObjName ),
1739 DLT_STRING(" New mode: "), DLT_INT( pstExistingClient->u32RegisteredMode),
1740 DLT_STRING(" Client: " ), DLT_UINT((guint) pstExistingClient->hClient) );
1742 if(pstExistingClient->u32RegisteredMode == NSM_SHUTDOWNTYPE_NOT)
1744 /* The client is not registered for at least one mode. Remove it from the list */
1745 NSM__vFreeLifecycleClientObject(pstExistingClient);
1746 NSM__pLifecycleClients = g_list_remove(NSM__pLifecycleClients, pstExistingClient);
1751 /* Warning: The client could not be found in the list of clients. */
1752 enRetVal = NsmErrorStatus_Parameter;
1753 DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to unregister lifecycle consumer."),
1754 DLT_STRING(" Bus name: "), DLT_STRING(sBusName),
1755 DLT_STRING(" Obj name: "), DLT_STRING(sObjName),
1756 DLT_STRING(" Unregistered mode(s): "), DLT_INT( u32ShutdownMode));
1763 /**********************************************************************************************************************
1765 * The function is used to get the state of the passed session.
1766 * It checks the passed parameters and creates a NsmSession_s structure of them.
1767 * If everything is ok, the state of the session will be determined and written to penSessionState.
1769 * @param sSessionName: Name of the session whose state just be returned
1770 * @param sSessionName: Owner of the session whose state just be returned
1771 * @param enSeatId: Seat of the session
1772 * @param penSessionState: Pointer where to store the session state
1773 * @param penRetVal: Pointer where to store the return value
1775 **********************************************************************************************************************/
1776 static NsmErrorStatus_e NSM__enOnHandleGetSessionState(const gchar *sSessionName,
1777 const NsmSeat_e enSeatId,
1778 NsmSessionState_e *penSessionState)
1780 /* Function local variables */
1781 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
1782 glong u32SessionNameLen = 0; /* Length of passed session owner */
1783 NsmSession_s stSearchSession = {0}; /* To search for existing session */
1785 /* Check if the passed parameters are valid */
1786 u32SessionNameLen = g_utf8_strlen(sSessionName, -1);
1788 if(u32SessionNameLen < NSM_MAX_SESSION_OWNER_LENGTH)
1790 /* Search for session with name, seat and owner. */
1791 stSearchSession.enSeat = enSeatId;
1792 g_strlcpy((gchar*) stSearchSession.sName, sSessionName, sizeof(stSearchSession.sName) );
1794 enRetVal = NSM__enGetSessionState(&stSearchSession);
1795 *penSessionState = stSearchSession.enState;
1799 /* Error: Invalid parameter. The session or owner name is to long. */
1800 enRetVal = NsmErrorStatus_Parameter;
1801 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to get session state. The session name is to long."),
1802 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1803 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ));
1810 /**********************************************************************************************************************
1812 * The function sets the state of a session to a passed value.
1813 * It checks the passed parameters and creates a NsmSession_s structure of them.
1814 * If everything is ok, the state of the session will be set accordingly.
1816 * @param sSessionName: Name of the session whose state just be set
1817 * @param sSessionOwner: Owner of the session
1818 * @param enSeatId: Seat of the session
1819 * @param enSessionState: New state of the session
1820 * @param penRetVal: Pointer where to store the return value
1822 **********************************************************************************************************************/
1823 static NsmErrorStatus_e NSM__enOnHandleSetSessionState(const gchar *sSessionName,
1824 const gchar *sSessionOwner,
1825 const NsmSeat_e enSeatId,
1826 const NsmSessionState_e enSessionState)
1828 /* Function local variables */
1829 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
1830 glong u32SessionNameLen = 0; /* Length of passed session owner */
1831 glong u32SessionOwnerLen = 0; /* Length of passed session name */
1832 NsmSession_s stSession = {0}; /* Session object passed to internal function */
1834 /* Check if the passed parameters are valid */
1835 u32SessionNameLen = g_utf8_strlen(sSessionName, -1);
1836 u32SessionOwnerLen = g_utf8_strlen(sSessionOwner, -1);
1838 if( (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH )
1839 && (u32SessionOwnerLen < NSM_MAX_SESSION_OWNER_LENGTH))
1841 /* Build session object to pass it internally */
1842 g_strlcpy((gchar*) stSession.sName, sSessionName, sizeof(stSession.sName) );
1843 g_strlcpy((gchar*) stSession.sOwner, sSessionOwner, sizeof(stSession.sOwner));
1845 stSession.enSeat = enSeatId;
1846 stSession.enState = enSessionState;
1848 enRetVal = NSM__enSetSessionState(&stSession, TRUE, TRUE);
1852 /* Error: Invalid parameter. The session or owner name is to long. */
1853 enRetVal = NsmErrorStatus_Parameter;
1854 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set session state. Invalid parameter."),
1855 DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
1856 DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
1857 DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ));
1864 /**********************************************************************************************************************
1866 * The helper function is called by 'NSM__boOnHandleSetAppHealthStatus', when an application became valid again.
1867 * It removes the application from the list of invalid apps.
1869 * @param pstFailedApp: Pointer to structure with information about the failed application.
1871 * @return NsmErrorStatus_Ok: The application has been removed from the list of failed apps.
1872 * NsmErrorStatus_WrongSession: The application has never been on the list of failed apps.
1874 **********************************************************************************************************************/
1875 static NsmErrorStatus_e NSM__enSetAppStateValid(NSM__tstFailedApplication* pstFailedApp)
1877 /* Function local variables */
1878 GSList *pAppListEntry = NULL; /* List entry of application */
1879 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
1880 NSM__tstFailedApplication *pstExistingApplication = NULL;
1882 /* An application has become valid again. Check if it really was invalid before. */
1883 pAppListEntry = g_slist_find_custom(NSM__pFailedApplications, pstFailedApp, &NSM__i32ApplicationCompare);
1885 if(pAppListEntry != NULL)
1887 /* We found at least one entry for the application. Remove it from the list */
1888 enRetVal = NsmErrorStatus_Ok;
1889 pstExistingApplication = (NSM__tstFailedApplication*) pAppListEntry->data;
1890 NSM__pFailedApplications = g_slist_remove(NSM__pFailedApplications, pstExistingApplication);
1891 NSM__vFreeFailedApplicationObject(pstExistingApplication);
1893 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: An application has become valid again." ),
1894 DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName));
1898 /* Error: There was no session registered for the application that failed. */
1899 enRetVal = NsmErrorStatus_Error;
1900 DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to set application valid. Application was never invalid."),
1901 DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName ));
1908 /**********************************************************************************************************************
1910 * The helper function is called by 'NSM__enSetAppStateFailed', when an application failed.
1911 * It looks for sessions that have been registered by the app.
1913 * @param pstFailedApp: Pointer to structure with information about the failed application.
1915 **********************************************************************************************************************/
1916 static void NSM__vDisableSessionsForApp(NSM__tstFailedApplication* pstFailedApp)
1918 /* Function local variables */
1919 GSList *pSessionListEntry = NULL;
1920 NsmSession_s *pstExistingSession = NULL;
1921 NsmSession_s stSearchSession = {0};
1923 /* Only set the "owner" of the session (to the AppName) to search for all sessions of the app. */
1924 g_strlcpy(stSearchSession.sOwner, pstFailedApp->sName, sizeof(stSearchSession.sOwner));
1926 g_mutex_lock(NSM__pSessionMutex);
1927 pSessionListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionOwnerCompare);
1929 if(pSessionListEntry != NULL)
1931 /* Found at least one session. */
1934 /* Get the session object for the list entry */
1935 pstExistingSession = (NsmSession_s*) pSessionListEntry->data;
1936 pstExistingSession->enState = NsmSessionState_Unregistered;
1938 /* Inform D-Bus and StateMachine that a session became invalid */
1939 NSM__vPublishSessionChange(pstExistingSession, TRUE, TRUE);
1941 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: A session has become invalid, because an application failed."),
1942 DLT_STRING(" Application: "), DLT_STRING(pstExistingSession->sOwner ),
1943 DLT_STRING(" Session: "), DLT_STRING(pstExistingSession->sName ),
1944 DLT_STRING(" Seat: "), DLT_INT( pstExistingSession->enSeat ),
1945 DLT_STRING(" State: "), DLT_INT( pstExistingSession->enState ));
1947 /* Remove or "reset" session */
1948 if(NSM__boIsPlatformSession(pstExistingSession) == TRUE)
1950 /* It is a default session. Don't remove it. Set owner to NSM again. */
1951 g_strlcpy(pstExistingSession->sOwner, NSM_DEFAULT_SESSION_OWNER, sizeof(pstExistingSession->sOwner));
1955 /* The session has been registered by a failed app. Remove it. */
1956 NSM__pSessions = g_slist_remove(NSM__pSessions, pstExistingSession);
1957 NSM__vFreeSessionObject(pstExistingSession);
1960 /* Try to find the next session that had been registered for the app. */
1961 pSessionListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionOwnerCompare);
1963 } while(pSessionListEntry != NULL);
1967 /* There have been no session registered for this application. */
1968 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: There had been no registered sessions." ),
1969 DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName));
1972 g_mutex_unlock(NSM__pSessionMutex);
1976 /**********************************************************************************************************************
1978 * The helper function is called by 'NSM__boOnHandleSetAppHealthStatus', when an application failed.
1980 * @param pstFailedApp: Pointer to structure with information about the failed application.
1982 * @return always "NsmErrorStatus_Ok"
1984 **********************************************************************************************************************/
1985 static NsmErrorStatus_e NSM__enSetAppStateFailed(NSM__tstFailedApplication* pstFailedApp)
1987 /* Function local variables */
1988 GSList *pFailedAppListEntry = NULL; /* List entry of application */
1989 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
1990 NSM__tstFailedApplication *pstFailedApplication = NULL;
1992 /* An application failed. Check if the application already is known as 'failed'. */
1993 pFailedAppListEntry = g_slist_find_custom(NSM__pFailedApplications, pstFailedApp, &NSM__i32ApplicationCompare);
1995 if(pFailedAppListEntry == NULL)
1997 /* The application is not on the list yet. Create it. */
1998 enRetVal = NsmErrorStatus_Ok;
2000 pstFailedApplication = g_new(NSM__tstFailedApplication, 1);
2001 g_strlcpy(pstFailedApplication->sName, pstFailedApp->sName, sizeof(pstFailedApplication->sName));
2002 NSM__pFailedApplications = g_slist_append(NSM__pFailedApplications, pstFailedApplication);
2004 /* Disable all session that have been registered by the application */
2005 NSM__vDisableSessionsForApp(pstFailedApplication);
2009 /* Warning: The application is already in the list of failed session. */
2010 enRetVal = NsmErrorStatus_Ok;
2011 DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: The application has already been marked as 'failed'."),
2012 DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName ));
2019 /**********************************************************************************************************************
2021 * The function is called when an application has become invalid or valid again.
2022 * If an application became inactive, it will be added to the list of failed applications
2023 * and signals for the session registered by the application will be emitted.
2024 * If an application became valid again, it will only be removed from the list of failed sessions.
2026 * @param sAppName: Application which changed its state.
2027 * @param boAppState: Indicates if the application became invalid or valid again.
2028 * @param penRetVal: Pointer where to store the return value
2030 **********************************************************************************************************************/
2031 static NsmErrorStatus_e NSM__enOnHandleSetAppHealthStatus(const gchar *sAppName,
2032 const gboolean boAppState)
2034 /* Function local variables */
2035 NSM__tstFailedApplication stSearchApplication = {0}; /* Temporary application object for search */
2036 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
2038 /* Check if passed parameters are valid */
2039 if(strlen(sAppName) < NSM_MAX_SESSION_OWNER_LENGTH)
2041 /* The application name is valid. Copy it for further checks. */
2042 g_strlcpy((gchar*) stSearchApplication.sName, sAppName, sizeof(stSearchApplication.sName));
2044 if(boAppState == TRUE)
2046 enRetVal = NSM__enSetAppStateValid(&stSearchApplication);
2050 enRetVal = NSM__enSetAppStateFailed(&stSearchApplication);
2055 /* Error: The passed application name is too long. */
2056 enRetVal = NsmErrorStatus_Parameter;
2057 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set application health status. The application name is too long."),
2058 DLT_STRING(" Owner: " ), DLT_STRING(sAppName ),
2059 DLT_STRING(" State: " ), DLT_INT(boAppState ));
2067 /**********************************************************************************************************************
2069 * The function returns the current AppHealthCount, which is stored in local variable.
2071 * @param pu32AppHealthCount: Pointer where to store the AppHealthCount (number of failed applications).
2073 **********************************************************************************************************************/
2074 static guint NSM__u32OnHandleGetAppHealthCount(void)
2076 return g_slist_length(NSM__pFailedApplications);
2080 /**********************************************************************************************************************
2082 * The function returns the current interface version of the NodeStateManager.
2084 * @param pu32InterfaceVersion: Pointer where to store the interface version.
2086 **********************************************************************************************************************/
2087 static guint NSM__u32OnHandleGetInterfaceVersion(void)
2089 /* Return interface version to caller. */
2090 return NSM_INTERFACE_VERSION;
2094 /**********************************************************************************************************************
2096 * The function initializes all file local variables
2098 **********************************************************************************************************************/
2099 static void NSM__vInitializeVariables(void)
2101 /* Initialize file local variables */
2102 NSM__pSessionMutex = NULL;
2103 NSM__pSessions = NULL;
2104 NSM__pLifecycleClients = NULL;
2105 NSM__pNodeStateMutex = NULL;
2106 NSM__enNodeState = NsmNodeState_NotSet;
2107 NSM__pApplicationModeMutex = NULL;
2108 NSM__enApplicationMode = NsmApplicationMode_NotSet;
2109 NSM__pFailedApplications = NULL;
2110 NSM__pCurrentLifecycleClient = NULL;
2114 /**********************************************************************************************************************
2116 * The function creates the platform sessions, configured in "NSM__asDefaultSessions".
2118 **********************************************************************************************************************/
2119 static void NSM__vCreatePlatformSessions(void)
2121 NsmSession_s *pNewDefaultSession = NULL;
2122 guint u32DefaultSessionIdx = 0;
2123 NsmSeat_e enSeatIdx = NsmSeat_NotSet;
2125 /* Configure the default sessions, which are always available */
2126 for(u32DefaultSessionIdx = 0;
2127 u32DefaultSessionIdx < sizeof(NSM__asDefaultSessions)/sizeof(gchar*);
2128 u32DefaultSessionIdx++)
2130 /* Create a session for every session name and seat */
2131 for(enSeatIdx = NsmSeat_NotSet + 1; enSeatIdx < NsmSeat_Last; enSeatIdx++)
2133 pNewDefaultSession = g_new0(NsmSession_s, 1);
2134 g_strlcpy((gchar*) pNewDefaultSession->sName, NSM__asDefaultSessions[u32DefaultSessionIdx], sizeof(pNewDefaultSession->sName));
2135 g_strlcpy((gchar*) pNewDefaultSession->sOwner, NSM_DEFAULT_SESSION_OWNER, sizeof(pNewDefaultSession->sOwner));
2136 pNewDefaultSession->enSeat = enSeatIdx;
2137 pNewDefaultSession->enState = NsmSessionState_Inactive;
2139 NSM__pSessions = g_slist_append(NSM__pSessions, pNewDefaultSession);
2145 /**********************************************************************************************************************
2147 * The function creates the mutexes used in the NSM.
2149 **********************************************************************************************************************/
2150 static void NSM__vCreateMutexes(void)
2152 /* Initialize the local mutexes */
2153 NSM__pNodeStateMutex = g_mutex_new();
2154 NSM__pApplicationModeMutex = g_mutex_new();
2155 NSM__pSessionMutex = g_mutex_new();
2159 /**********************************************************************************************************************
2161 * The function deletes the mutexes used in the NSM.
2163 **********************************************************************************************************************/
2164 static void NSM__vDeleteMutexes(void)
2166 /* Delete the local mutexes */
2167 g_mutex_free(NSM__pNodeStateMutex);
2168 g_mutex_free(NSM__pApplicationModeMutex);
2169 g_mutex_free(NSM__pSessionMutex);
2173 /**********************************************************************************************************************
2175 * The function is called to trace a syslog message for a shutdown client.
2177 * @param sBus: Bus name of the shutdown client.
2178 * @param sObj: Object name of the lifecycle client.
2179 * @param u32Reason: Shutdown reason send to the client.
2180 * @param sInOut: "enter" or "leave" (including failure reason)
2181 * @param enErrorStatus: Error value
2183 **********************************************************************************************************************/
2184 static void NSM__vLtProf(gchar *sBus, gchar *sObj, guint32 u32Reason, gchar *sInOut, NsmErrorStatus_e enErrorStatus)
2186 gchar pszLtprof[128] = "LTPROF: bus:%s obj:%s (0x%08X:%d) ";
2187 guint32 dwLength = 128;
2189 g_strlcat(pszLtprof, sInOut, dwLength);
2193 if(u32Reason == NSM_SHUTDOWNTYPE_RUNUP)
2195 g_strlcat(pszLtprof, "runup", dwLength);
2199 g_strlcat(pszLtprof, "shutdown", dwLength);
2203 syslog(LOG_NOTICE, (char *)pszLtprof, sBus, sObj, u32Reason, enErrorStatus);
2207 /**********************************************************************************************************************
2209 * The function is used to initialize syslog
2211 **********************************************************************************************************************/
2212 static void NSM__vSyslogOpen(void)
2214 openlog("NSM", LOG_PID, LOG_USER);
2218 /**********************************************************************************************************************
2220 * The function is used to deinitialize syslog
2222 **********************************************************************************************************************/
2223 static void NSM__vSyslogClose(void)
2229 /**********************************************************************************************************************
2231 * Interfaces. Exported functions. See Header for detailed description.
2233 **********************************************************************************************************************/
2236 /* The function is called by the NodeStateMachine to set a "property" of the NSM. */
2237 NsmErrorStatus_e NsmSetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen)
2239 /* Function local variables */
2240 NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
2242 /* Check which data the NSMC wants to set */
2245 /* NSMC wants to set the NodeState */
2246 case NsmDataType_NodeState:
2247 enRetVal = (u32DataLen == sizeof(NsmNodeState_e))
2248 ? NSM__enSetNodeState((NsmNodeState_e) *pData, TRUE, FALSE)
2249 : NsmErrorStatus_Parameter;
2252 /* NSMC wants to set the AppMode */
2253 case NsmDataType_AppMode:
2254 enRetVal = (u32DataLen == sizeof(NsmApplicationMode_e))
2255 ? NSM__enSetApplicationMode((NsmApplicationMode_e) *pData, TRUE, FALSE)
2256 : NsmErrorStatus_Parameter;
2259 /* NSMC wants to set the BootMode */
2260 case NsmDataType_BootMode:
2261 enRetVal = (u32DataLen == sizeof(gint))
2262 ? NSM__enSetBootMode((gint) *pData, FALSE)
2263 : NsmErrorStatus_Parameter;
2266 /* NSMC wants to set the ShutdownReason */
2267 case NsmDataType_ShutdownReason:
2268 enRetVal = (u32DataLen == sizeof(NsmShutdownReason_e))
2269 ? NSM__enSetShutdownReason((NsmShutdownReason_e) *pData, FALSE)
2270 : NsmErrorStatus_Parameter;
2273 /* NSMC wants to set a SessionState */
2274 case NsmDataType_SessionState:
2275 enRetVal = (u32DataLen == sizeof(NsmSession_s))
2276 ? NSM__enSetSessionState((NsmSession_s*) pData, TRUE, FALSE)
2277 : NsmErrorStatus_Parameter;
2280 /* Error: The type of the data NSMC is trying to set is unknown or the data is read only! */
2281 case NsmDataType_RestartReason:
2282 case NsmDataType_RunningReason:
2284 enRetVal = NsmErrorStatus_Parameter;
2292 /* The function is called by the NodeStateMachine to get a "property" of the NSM. */
2293 int NsmGetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen)
2295 /* Function local variables */
2296 int i32RetVal = -1; /* Return value. Positive: Amount of written bytes.
2297 Negative: An error occurred. */
2299 /* Check which data the NSMC wants to get */
2302 /* NSMC wants to get the NodeState */
2303 case NsmDataType_NodeState:
2304 if(u32DataLen == sizeof(NsmNodeState_e))
2306 if(NSM__enGetNodeState((NsmNodeState_e*) pData) == NsmErrorStatus_Ok)
2308 i32RetVal = sizeof(NsmNodeState_e);
2313 /* NSMC wants to get the ApplicationMode */
2314 case NsmDataType_AppMode:
2315 if(u32DataLen == sizeof(NsmApplicationMode_e))
2317 if(NSM__enGetApplicationMode((NsmApplicationMode_e*) pData) == NsmErrorStatus_Ok)
2319 i32RetVal = sizeof(NsmApplicationMode_e);
2324 /* NSMC wants to get the BootMode */
2325 case NsmDataType_BootMode:
2326 if(u32DataLen == sizeof(gint))
2328 if(NSMA_boGetBootMode((gint*) pData) == TRUE)
2330 i32RetVal = sizeof(gint);
2335 /* NSMC wants to get the RunningReason */
2336 case NsmDataType_RunningReason:
2337 if(u32DataLen == sizeof(NsmRunningReason_e))
2339 if(NSMA_boGetRunningReason((NsmRunningReason_e*) pData) == TRUE)
2341 i32RetVal = sizeof(NsmRunningReason_e);
2346 /* NSMC wants to get the ShutdownReason */
2347 case NsmDataType_ShutdownReason:
2348 if(u32DataLen == sizeof(NsmShutdownReason_e))
2350 if(NSMA_boGetShutdownReason((NsmShutdownReason_e*) pData) == TRUE)
2352 i32RetVal = sizeof(NsmShutdownReason_e);
2357 /* NSMC wants to get the RestartReason */
2358 case NsmDataType_RestartReason:
2359 if(u32DataLen == sizeof(NsmRestartReason_e))
2361 if(NSMA_boGetRestartReason((NsmRestartReason_e*) pData) == TRUE)
2363 i32RetVal = sizeof(NsmRestartReason_e);
2368 /* NSMC wants to get the SessionState */
2369 case NsmDataType_SessionState:
2370 if(u32DataLen == sizeof(NsmSession_s))
2372 if(NSM__enGetSessionState((NsmSession_s*) pData) == NsmErrorStatus_Ok)
2374 i32RetVal = sizeof(NsmSession_s);
2379 /* Error: The type of the data NSMC is trying to set is unknown. */
2389 unsigned int NsmGetInterfaceVersion(void)
2391 return NSM_INTERFACE_VERSION;
2395 /* The main function of the NodeStateManager */
2398 gboolean boEndByUser = FALSE;
2400 /* Initialize glib for using "g" types */
2403 /* Register NSM for DLT */
2404 DLT_REGISTER_APP("NSM", "Node State Manager");
2405 DLT_REGISTER_CONTEXT(NsmContext, "005", "Context for the NSM");
2406 DLT_ENABLE_LOCAL_PRINT();
2408 /* Initialize syslog */
2411 /* Print first msg. to show that NSM is going to start */
2412 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: NodeStateManager started."));
2414 /* Currently no other resources accessing the NSM. Prepare it now! */
2415 NSM__vInitializeVariables(); /* Initialize file local variables*/
2416 NSM__vCreatePlatformSessions(); /* Create platform sessions */
2417 NSM__vCreateMutexes(); /* Create mutexes */
2419 /* Initialize the NSMA before the NSMC, because the NSMC can access properties */
2420 if(NSMA_boInit(&NSM__stObjectCallBacks) == TRUE)
2422 /* Set the properties to initial values */
2423 (void) NSMA_boSetBootMode(0);
2424 (void) NSMA_boSetRestartReason(NsmRestartReason_NotSet);
2425 (void) NSMA_boSetShutdownReason(NsmShutdownReason_NotSet);
2426 (void) NSMA_boSetRunningReason(NsmRunningReason_WakeupCan);
2428 /* Initialize/start the NSMC */
2429 if(NsmcInit() == 0x01)
2431 /* The event loop is only canceled if the Node is completely shut down or there is an internal error. */
2432 boEndByUser = NSMA_boWaitForEvents();
2434 if(boEndByUser == TRUE)
2436 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Successfully canceled event loop. "),
2437 DLT_STRING("Shutting down NodeStateManager." ));
2441 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Error in event loop. " ),
2442 DLT_STRING("Shutting down NodeStateManager."));
2445 /* The event loop returned. Clean up the NSMA. */
2446 (void) NSMA_boDeInit();
2450 /* Error: Failed to initialize the NSMC. Clean up NSMA, because it is not needed anymore. */
2451 (void) NSMA_boDeInit();
2452 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Error. Failed to initialize the NSMC."));
2457 /* Error: Failed to initialize the NSMA. */
2458 DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Error. Failed to initialize the NSMA."));
2461 /* Free the mutexes */
2462 NSM__vDeleteMutexes();
2464 /* Remove data from all lists */
2465 g_slist_free_full(NSM__pSessions, &NSM__vFreeSessionObject);
2466 g_slist_free_full(NSM__pFailedApplications, &NSM__vFreeFailedApplicationObject);
2467 g_list_free_full (NSM__pLifecycleClients, &NSM__vFreeLifecycleClientObject);
2469 DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: NodeStateManager stopped."));
2472 NSM__vSyslogClose();
2474 /* Unregister NSM from DLT */
2475 DLT_UNREGISTER_CONTEXT(NsmContext);
2476 DLT_UNREGISTER_APP();