summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog26
-rw-r--r--NEWS35
-rw-r--r--NodeStateAccess/Makefile.am12
-rw-r--r--NodeStateAccess/NodeStateAccess.c33
-rw-r--r--NodeStateMachineStub/NodeStateMachine.c4
-rw-r--r--NodeStateMachineStub/NodeStateMachine.h8
-rw-r--r--NodeStateManager/Makefile.am43
-rw-r--r--NodeStateManager/NodeStateManager.c602
-rw-r--r--NodeStateManager/NodeStateManager.h15
-rw-r--r--NodeStateManager/NodeStateTypes.h5
-rw-r--r--NodeStateManager/config/node-state-manager.pc.in2
-rw-r--r--NodeStateManager/config/nodestatemanager-daemon.service.in8
-rw-r--r--NodeStateTest/NodeStateTest.c148
-rw-r--r--configure.ac20
14 files changed, 715 insertions, 246 deletions
diff --git a/ChangeLog b/ChangeLog
index 29568d9..badaa2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+16th Oct. 2013, Jean-Pierre Bogler:
+ - Introduced parameters for restart reason and
+ type in NSMC call.
+
+19th Sep. 2013, Jean-Pierre Bogler:
+ - Temporary fix to return the ApplicationMode
+ in which we initially were in and not the
+ ApplicationMode that recently was set.
+ - Added dependency to pas-daemon.service to
+ assert stable PCL handling.
+
+09th Sep. 2013, Jean-Pierre Bogler:
+ - Moved reading of "ApplicationMode" via PCL in
+ the "Getter function", since we can't use PCL
+ until the dbus interface is exported (because
+ the PCL needs the dbus interface to register)
+
+02nd Aug. 2013, Jean-Pierre Bogler:
+ - Introduced PCL in NSM to store ApplicationMode
+
+01st Aug. 2013, Jean-Pierre Bogler:
+ - Minor fixes and changes
+
+18th Apr. 2013, Jean-Pierre Bogler:
+ - Allow NSMC to register sessions
+
15th Mar. 2013, Jean-Pierre Bogler:
- Introduced NodeStateAccess
- Introduced NodeStateTest
diff --git a/NEWS b/NEWS
index 24338f9..d31252f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,38 @@
+1.3.5
+=====
+* Extended interface of NodeStateMachine (NSMC)
+
+1.3.4
+=====
+* Temporary workaround for ApplicationMode handling
+* New startup dependency to "pas-daemon.service"
+
+1.3.3
+=====
+* Bugfix for PCL handling
+
+1.3.2
+=====
+* NSM stores ApplicationMode in persistence.
+
+1.2.2
+=====
+* NSM does not terminate automatically on dbus lost.
+* NSM prints version number at start up.
+
+1.2.1
+=====
+* Added enumeration values and functions to allow the
+* NodeStateMachine (NSMC) the registration of sessions.
+
+1.2.0
+=====
+* Set up 1.2.0 as version number for the first really
+* usable version, after some changes due to licensing
+* issues had to be done.
+* Included productive NodeStateAccess (NSMA) library
+* sources in NSM to avoid delivering a stub.
+
0.1.0
=====
* Initial release of the NodeStateManager
diff --git a/NodeStateAccess/Makefile.am b/NodeStateAccess/Makefile.am
index d7d846d..ea33d77 100644
--- a/NodeStateAccess/Makefile.am
+++ b/NodeStateAccess/Makefile.am
@@ -21,12 +21,12 @@ libNodeStateAccess_la_SOURCES = NodeStateAccess.c \
generated/NodeStateLifecycleControl.c \
generated/NodeStateLifecycleConsumer.c
-libNodeStateAccess_la_CFLAGS = -I generated \
- $(GIO_CFLAGS) \
- $(GIO_UNIX_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(GOBJECT_CFLAGS) \
- $(NSM_CFLAGS)
+libNodeStateAccess_la_CFLAGS = -I$(top_srcdir)/NodeStateManager \
+ -I generated \
+ $(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GOBJECT_CFLAGS)
libNodeStateAccess_la_LIBDADD = $(GIO_LIBS) \
$(GIO_UNIX_LIBS) \
diff --git a/NodeStateAccess/NodeStateAccess.c b/NodeStateAccess/NodeStateAccess.c
index 85a5284..c167247 100644
--- a/NodeStateAccess/NodeStateAccess.c
+++ b/NodeStateAccess/NodeStateAccess.c
@@ -15,10 +15,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
-* Date Author Reason
-* 24.10.2012 Jean-Pierre Bogler CSP_WZ#1322: Initial creation
-* 24.01.2013 Jean-Pierre Bogler CSP_WZ#1194: Fixed bug. LifecycleRequestComnplete did not send dbus response.
-*
**********************************************************************************************************************/
@@ -32,6 +28,7 @@
#include "gio/gio.h" /* glib types */
#include "NodeStateAccess.h" /* own header */
#include "NodeStateTypes.h" /* Type defintions of the NSM */
+#include <glib-unix.h> /* Catch SIGTERM */
/* additional includes to use D-Bus */
#include "string.h" /* memcpy, memset, etc. */
@@ -158,6 +155,9 @@ static void NSMA__vOnBusAcquired (GDBusConnection *pConnection, const gchar* sNa
static void NSMA__vOnNameAcquired(GDBusConnection *pConnection, const gchar* sName, gpointer pUserData);
static void NSMA__vOnNameLost (GDBusConnection *pConnection, const gchar* sName, gpointer pUserData);
+/* Linux signal callback */
+static gboolean NSMA__boOnHandleSigterm(gpointer pUserData);
+
/* Internal callback for async. life cycle client returns */
static void NSMA__vOnLifecycleRequestFinish(GObject *pSrcObject, GAsyncResult *pRes, gpointer pUserData);
@@ -666,6 +666,11 @@ static void NSMA__vOnBusAcquired(GDBusConnection *pConnection, const gchar* sNam
/* Store the connection. Needed later, to create life cycle clients. */
NSMA__pBusConnection = pConnection;
+ /* Do not automatically exit the main loop when connection is lost.
+ * The program terminates nevertheless, but will give useful traces.
+ */
+ g_dbus_connection_set_exit_on_close(NSMA__pBusConnection, FALSE);
+
/* Register the callbacks */
(void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-set-boot-mode", G_CALLBACK(NSMA__boOnHandleSetBootMode), NULL);
(void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-set-node-state", G_CALLBACK(NSMA__boOnHandleSetNodeState), NULL);
@@ -861,6 +866,23 @@ static gboolean NSMA__boOnHandleLifecycleRequestComplete(NodeStateConsumer *
/**********************************************************************************************************************
*
+* The function is called when the SIGTERM signal is received
+*
+* @param pUserData: Optional user data (not used)
+* @return TRUE: Keep callback installed
+*
+**********************************************************************************************************************/
+static gboolean NSMA__boOnHandleSigterm(gpointer pUserData)
+{
+ NSMA__boLoopEndByUser = TRUE;
+ g_main_loop_quit(NSMA__pMainLoop);
+
+ return TRUE;
+}
+
+
+/**********************************************************************************************************************
+*
* Interfaces. Exported functions. See Header for detailed description.
*
**********************************************************************************************************************/
@@ -942,6 +964,9 @@ gboolean NSMA_boWaitForEvents(void)
NULL,
NULL);
+ /* Add source to catch SIGTERM signal (#15) */
+ g_unix_signal_add(15, &NSMA__boOnHandleSigterm, NULL);
+
/* Run main loop to get D-Bus connection and export objects. The function will only return,
* if there was an internal error or it has been cancelled by the user.
*/
diff --git a/NodeStateMachineStub/NodeStateMachine.c b/NodeStateMachineStub/NodeStateMachine.c
index 07f22c1..c890658 100644
--- a/NodeStateMachineStub/NodeStateMachine.c
+++ b/NodeStateMachineStub/NodeStateMachine.c
@@ -94,9 +94,9 @@ NsmErrorStatus_e NsmcSetData(NsmDataType_e enData, unsigned char *pData, unsigne
}
-unsigned char NsmcRequestNodeRestart(void)
+unsigned char NsmcRequestNodeRestart(NsmRestartReason_e enRestartReason, unsigned int u32RestartType)
{
- printf("NSMC: NsmcRequestNodeRestart called.\n");
+ printf("NSMC: NsmcRequestNodeRestart called. Restart reason: %d. RestartType: 0x%02X\n", enRestartReason, u32RestartType);
return 1;
}
diff --git a/NodeStateMachineStub/NodeStateMachine.h b/NodeStateMachineStub/NodeStateMachine.h
index c486d20..d745602 100644
--- a/NodeStateMachineStub/NodeStateMachine.h
+++ b/NodeStateMachineStub/NodeStateMachine.h
@@ -16,12 +16,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
-* Date Author Reason
-* 27.09.2012 Jean-Pierre Bogler CSP_WZ#1194: Initial creation.
-* 24.10.2012 Jean-Pierre Bogler CSP_WZ#1322: Changed parameter types of interface functions.
-* No change of major interface version, because
-* the same native types are used.
-*
**********************************************************************************************************************/
#ifdef __cplusplus
@@ -108,7 +102,7 @@ NsmErrorStatus_e NsmcSetData(NsmDataType_e enData, unsigned char *pData, unsigne
\retval true: The request for the restart could be processed. false: Error processing the restart request.
This will be used by the NSM to request a node restart when requested by one of its clients.*/
-unsigned char NsmcRequestNodeRestart(void);
+unsigned char NsmcRequestNodeRestart(NsmRestartReason_e enRestartReason, unsigned int u32RestartType);
/** \brief Get version of the interface
diff --git a/NodeStateManager/Makefile.am b/NodeStateManager/Makefile.am
index 260ca74..d3e9f50 100644
--- a/NodeStateManager/Makefile.am
+++ b/NodeStateManager/Makefile.am
@@ -18,28 +18,27 @@ bin_PROGRAMS = NodeStateManager
NodeStateManager_SOURCES = NodeStateManager.c
-NodeStateManager_CFLAGS = \
- -I$(top_srcdir)/NodeStateMachineStub \
- -I$(top_srcdir)/NodeStateAccess \
- $(DLT_CFLAGS) \
- $(GIO_CFLAGS) \
- $(GIO_UNIX_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(GOBJECT_CFLAGS) \
- $(PLATFORM_CFLAGS)
-
-NodeStateManager_LDFLAGS = \
- $(PLATFORM_LDFLAGS) \
- -export-dynamic
-
-NodeStateManager_LDADD = \
- -L$(top_srcdir)/NodeStateAccess -lNodeStateAccess \
- -L$(top_srcdir)/NodeStateMachineStub -lNodeStateMachine \
- $(DLT_LIBS) \
- $(GIO_LIBS) \
- $(GIO_UNIX_LIBS) \
- $(GLIB_LIBS) \
- $(GOBJECT_LIBS)
+NodeStateManager_CFLAGS = -I$(top_srcdir)/NodeStateMachineStub \
+ -I$(top_srcdir)/NodeStateAccess \
+ $(DLT_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GOBJECT_CFLAGS) \
+ $(SYSTEMD_CFLAGS) \
+ $(PCL_CFLAGS)
+
+NodeStateManager_LDFLAGS = -export-dynamic
+
+NodeStateManager_LDADD = -L$(top_srcdir)/NodeStateAccess -lNodeStateAccess \
+ -L$(top_srcdir)/NodeStateMachineStub -lNodeStateMachine \
+ $(DLT_LIBS) \
+ $(GIO_LIBS) \
+ $(GIO_UNIX_LIBS) \
+ $(GLIB_LIBS) \
+ $(GOBJECT_LIBS) \
+ $(SYSTEMD_LIBS) \
+ $(PCL_LIBS)
include_HEADERS = NodeStateManager.h NodeStateTypes.h
diff --git a/NodeStateManager/NodeStateManager.c b/NodeStateManager/NodeStateManager.c
index 4ed5150..6051183 100644
--- a/NodeStateManager/NodeStateManager.c
+++ b/NodeStateManager/NodeStateManager.c
@@ -1,6 +1,6 @@
/**********************************************************************************************************************
*
-* Copyright (C) 2012 Continental Automotive Systems, Inc.
+* Copyright (C) 2013 Continental Automotive Systems, Inc.
*
* Author: Jean-Pierre.Bogler@continental-corporation.com
*
@@ -16,31 +16,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
-* Date Author Reason
-* 20.06.2012 Jean-Pierre Bogler CSP_WZ#388: Initial creation
-* 19.09.2012 Jean-Pierre Bogler OvipRbt#135: Added new default sessions for product, thermal and power
-* management. Fixed bug, when calling 'GetSessionState'.
-* Undefined parameter 'SessionOwner' was used.
-* 27.09.2012 Jean-Pierre Bogler CSP_WZ#1194: Changed file header structure and license to be released
-* as open source package. Introduced 'NodeStateTypes.h' to
-* avoid circle includes and encapsulate type definitions.
-* 08.10.2012 Jean-Pierre Bogler CSP_WZ#951: Introduced improvements and changes from 4-eye review:
-* - Changed handling of failed applications
-* - Changed handling of platform sessions
-* - Fixed some QAC warnings
-* - Added deallocation of GError objects
-* 24.10.2012 Jean-Pierre Bogler CSP_WZ#1322: The NSM does not use generated D-Bus objects anymore,
-* due to legal restrictions. Instead, it registers
-* callbacks at the NodeStateAccess library NSMA.
-* Therefore, the parameters of the callbacks changed.
-* In addition, the establishment of the connection and
-* the handling of life cycle clients (timeout observation)
-* is done by the NSMA.
-* 01.11.2012 C. Domke CSP_WZ#666: Instrumented with LTPRO messages
-* 10.01.2013 Jean-Pierre Bogler CSP_WZ#1322: Initialize variables at declaration instead of using
-* memset and use g_utf8_strlen instead of strlen to
-* simplify configure srcipt (avoid some checks).
-*
**********************************************************************************************************************/
@@ -49,14 +24,18 @@
* Header includes
*
**********************************************************************************************************************/
-#include "NodeStateManager.h" /* Own Header file */
-#include "NodeStateTypes.h" /* Typedefinitions to use the NSM */
-#include "string.h" /* Memcpy etc. */
-#include "gio/gio.h" /* GLib lists */
-#include "dlt/dlt.h" /* DLT Log'n'Trace */
-#include "NodeStateMachine.h" /* Talk to NodeStateMachine */
-#include "NodeStateAccess.h" /* Access the IPC (D-Bus) */
-#include "syslog.h" /* Syslog messages */
+#include "NodeStateManager.h" /* Own Header file */
+#include "NodeStateTypes.h" /* Typedefinitions to use the NSM */
+#include "string.h" /* Memcpy etc. */
+#include "gio/gio.h" /* GLib lists */
+#include "dlt/dlt.h" /* DLT Log'n'Trace */
+#include "NodeStateMachine.h" /* Talk to NodeStateMachine */
+#include "NodeStateAccess.h" /* Access the IPC (D-Bus) */
+#include "syslog.h" /* Syslog messages */
+#include <systemd/sd-daemon.h> /* Systemd wdog */
+#include <persistence_client_library.h> /* Init/DeInit PCL */
+#include <persistence_client_library_key.h> /* Access persistent data */
+
/**********************************************************************************************************************
*
@@ -64,6 +43,10 @@
*
**********************************************************************************************************************/
+/* Defines to access persistence keys */
+#define NSM_PERS_APPLICATION_MODE_DB 0xFF
+#define NSM_PERS_APPLICATION_MODE_KEY "ERG_OIP_NSM_NODE_APPMODE"
+
/* The type defines the structure for a lifecycle consumer client */
typedef struct
{
@@ -132,6 +115,12 @@ static void NSM__vOnLifecycleRequestFinish(const NsmErrorStatus_e enErrorStatus)
/* Internal functions, to set and get values. Indirectly used by D-Bus and StateMachine */
+static NsmErrorStatus_e NSM__enRegisterSession (NsmSession_s *session,
+ gboolean boInformBus,
+ gboolean boInformMachine);
+static NsmErrorStatus_e NSM__enUnRegisterSession (NsmSession_s *session,
+ gboolean boInformBus,
+ gboolean boInformMachine);
static NsmErrorStatus_e NSM__enSetNodeState (NsmNodeState_e enNodeState,
gboolean boInformBus,
gboolean boInformMachine);
@@ -207,6 +196,9 @@ static void NSM__vLtProf(gchar *pszBus, gchar *pszObj, guint32 dwReason, gchar *
static void NSM__vSyslogOpen(void);
static void NSM__vSyslogClose(void);
+/* Systemd watchdog functions */
+static gboolean NSM__boOnHandleTimerWdog(gpointer pUserData);
+static void NSM__vConfigureWdogTimer(void);
/**********************************************************************************************************************
*
@@ -226,8 +218,11 @@ static GList *NSM__pLifecycleClients = NULL;
static GMutex *NSM__pNodeStateMutex = NULL;
static NsmNodeState_e NSM__enNodeState = NsmNodeState_NotSet;
-static GMutex *NSM__pApplicationModeMutex = NULL;
-static NsmApplicationMode_e NSM__enApplicationMode = NsmApplicationMode_NotSet;
+static GMutex *NSM__pNextApplicationModeMutex = NULL;
+static GMutex *NSM__pThisApplicationModeMutex = NULL;
+static NsmApplicationMode_e NSM__enNextApplicationMode = NsmApplicationMode_NotSet;
+static NsmApplicationMode_e NSM__enThisApplicationMode = NsmApplicationMode_NotSet;
+static gboolean NSM__boThisApplicationModeRead = FALSE;
static GSList *NSM__pFailedApplications = NULL;
@@ -289,6 +284,158 @@ static gboolean NSM__boIsPlatformSession(NsmSession_s *pstSession)
}
+/**
+* NSM__enRegisterSession:
+* @session: Ptr to NsmSession_s structure containing data to register a session
+* @boInformBus: Flag whether the a dbus signal should be send to inform about the new session
+* @boInformMachine: Flag whether the NSMC should be informed about the new session
+*
+* The internal function is used to register a session. It is either called from the dbus callback
+* or it is called via the internal context of the NSMC.
+*/
+static NsmErrorStatus_e NSM__enRegisterSession(NsmSession_s *session, gboolean boInformBus, gboolean boInformMachine)
+{
+ /* Function local variables */
+ NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
+ NsmSession_s *pNewSession = NULL; /* Pointer to new created session */
+ GSList *pListEntry = NULL; /* Pointer to list entry */
+
+ if( (g_strcmp0(session->sOwner, NSM_DEFAULT_SESSION_OWNER) != 0)
+ && (session->enState > NsmSessionState_Unregistered))
+ {
+ if(NSM__boIsPlatformSession(session) == FALSE)
+ {
+ g_mutex_lock(NSM__pSessionMutex);
+
+ pListEntry = g_slist_find_custom(NSM__pSessions, session, &NSM__i32SessionNameSeatCompare);
+
+ if(pListEntry == NULL)
+ {
+ enRetVal = NsmErrorStatus_Ok;
+
+ pNewSession = g_new0(NsmSession_s, 1);
+ memcpy(pNewSession, session, sizeof(NsmSession_s));
+
+ DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Registered session." ),
+ DLT_STRING(" Name: " ), DLT_STRING(session->sName ),
+ DLT_STRING(" Owner: " ), DLT_STRING(session->sOwner ),
+ DLT_STRING(" Seat: " ), DLT_INT((gint) session->enSeat ),
+ DLT_STRING(" Initial state: "), DLT_INT((gint) session->enState));
+
+ /* Return OK and append new object */
+ NSM__pSessions = g_slist_append(NSM__pSessions, pNewSession);
+
+ /* Inform D-Bus and StateMachine about the new session. */
+ NSM__vPublishSessionChange(pNewSession, boInformBus, boInformMachine);
+ }
+ else
+ {
+ /* Error: The session already exists. Don't store passed state. */
+ enRetVal = NsmErrorStatus_WrongSession;
+ DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to register session. Session already exists."),
+ DLT_STRING(" Name: " ), DLT_STRING(session->sName ),
+ DLT_STRING(" Owner: " ), DLT_STRING(session->sOwner ),
+ DLT_STRING(" Seat: " ), DLT_INT((gint) session->enSeat ),
+ DLT_STRING(" Initial state: "), DLT_INT((gint) session->enState ));
+ }
+
+ g_mutex_unlock(NSM__pSessionMutex);
+ }
+ else
+ {
+ /* Error: It is not allowed to re-register a default session! */
+ enRetVal = NsmErrorStatus_Parameter;
+ DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to register session. Re-Registration of default session not allowed."),
+ DLT_STRING(" Name: " ), DLT_STRING(session->sName ),
+ DLT_STRING(" Owner: " ), DLT_STRING(session->sOwner ),
+ DLT_STRING(" Seat: " ), DLT_INT((gint) session->enSeat ),
+ DLT_STRING(" Initial state: "), DLT_INT((gint) session->enState ));
+ }
+ }
+ else
+ {
+ /* Error: A parameter with an invalid value has been passed */
+ enRetVal = NsmErrorStatus_Parameter;
+ DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to register session. Invalid owner or state."),
+ DLT_STRING(" Name: " ), DLT_STRING(session->sName ),
+ DLT_STRING(" Owner: " ), DLT_STRING(session->sOwner ),
+ DLT_STRING(" Seat: " ), DLT_INT((gint) session->enSeat ),
+ DLT_STRING(" Initial state: "), DLT_INT((gint) session->enState ));
+ }
+
+ return enRetVal;
+}
+
+
+/**
+* NSM__enUnRegisterSession:
+* @session: Ptr to NsmSession_s structure containing data to unregister a session
+* @boInformBus: Flag whether the a dbus signal should be send to inform about the lost session
+* @boInformMachine: Flag whether the NSMC should be informed about the lost session
+*
+* The internal function is used to unregister a session. It is either called from the dbus callback
+* or it is called via the internal context of the NSMC.
+*/
+static NsmErrorStatus_e NSM__enUnRegisterSession(NsmSession_s *session, gboolean boInformBus, gboolean boInformMachine)
+{
+ /* Function local variables */
+ NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
+ NsmSession_s *pExistingSession = NULL; /* Pointer to existing session */
+ GSList *pListEntry = NULL; /* Pointer to list entry */
+
+ if(NSM__boIsPlatformSession(session) == FALSE)
+ {
+ g_mutex_lock(NSM__pSessionMutex);
+
+ pListEntry = g_slist_find_custom(NSM__pSessions, session, &NSM__i32SessionOwnerNameSeatCompare);
+
+ /* Check if the session exists */
+ if(pListEntry != NULL)
+ {
+ /* Found the session in the list. Now remove it. */
+ enRetVal = NsmErrorStatus_Ok;
+ pExistingSession = (NsmSession_s*) pListEntry->data;
+
+ DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Unregistered session." ),
+ DLT_STRING(" Name: " ), DLT_STRING(pExistingSession->sName ),
+ DLT_STRING(" Owner: " ), DLT_STRING(pExistingSession->sOwner ),
+ DLT_STRING(" Seat: " ), DLT_INT( pExistingSession->enSeat ),
+ DLT_STRING(" Last state: "), DLT_INT( pExistingSession->enState));
+
+ pExistingSession->enState = NsmSessionState_Unregistered;
+
+ /* Inform D-Bus and StateMachine about the unregistered session */
+ NSM__vPublishSessionChange(pExistingSession, boInformBus, boInformMachine);
+
+ NSM__vFreeSessionObject(pExistingSession);
+ NSM__pSessions = g_slist_remove(NSM__pSessions, pExistingSession);
+ }
+ else
+ {
+ /* Error: The session is unknown. */
+ enRetVal = NsmErrorStatus_WrongSession;
+ DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to unregister session. Session unknown."),
+ DLT_STRING(" Name: " ), DLT_STRING(session->sName ),
+ DLT_STRING(" Owner: " ), DLT_STRING(session->sOwner ),
+ DLT_STRING(" Seat: " ), DLT_INT((gint) session->enSeat ));
+ }
+
+ g_mutex_unlock(NSM__pSessionMutex);
+ }
+ else
+ {
+ /* Error: Failed to unregister session. The passed session is a "platform" session. */
+ enRetVal = NsmErrorStatus_WrongSession;
+ DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to unregister session. The session is a platform session."),
+ DLT_STRING(" Name: " ), DLT_STRING(session->sName ),
+ DLT_STRING(" Owner: " ), DLT_STRING(session->sOwner ),
+ DLT_STRING(" Seat: " ), DLT_INT((gint) session->enSeat ));
+ }
+
+ return enRetVal;
+}
+
+
/**********************************************************************************************************************
*
* The function is called from IPC and StateMachine to set the NodeState.
@@ -444,49 +591,106 @@ static NsmErrorStatus_e NSM__enSetBootMode(const gint i32BootMode, gboolean boIn
* @return see NsmErrorStatus_e
*
**********************************************************************************************************************/
-static NsmErrorStatus_e NSM__enSetApplicationMode(NsmApplicationMode_e enApplicationMode, gboolean boInformBus, gboolean boInformMachine)
+static NsmErrorStatus_e
+NSM__enSetApplicationMode(NsmApplicationMode_e enApplicationMode,
+ gboolean boInformBus,
+ gboolean boInformMachine)
{
- /* Function local variables */
- NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
+ /* Function local variables */
+ NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */
+ int pcl_return = 0;
/* Check if the passed parameter is valid */
- if((enApplicationMode > NsmApplicationMode_NotSet) && (enApplicationMode < NsmApplicationMode_Last))
+ if( (enApplicationMode > NsmApplicationMode_NotSet)
+ && (enApplicationMode < NsmApplicationMode_Last ))
{
/* The passed parameter is valid. Return OK */
enRetVal = NsmErrorStatus_Ok;
- g_mutex_lock(NSM__pApplicationModeMutex);
+ g_mutex_lock(NSM__pNextApplicationModeMutex);
- /* Only store the new value and emit a signal, if the new value is different */
- if(NSM__enApplicationMode != enApplicationMode)
+ /* Only store new value and emit signal, if new value is different */
+ if(NSM__enNextApplicationMode != enApplicationMode)
{
/* Store new value and emit signal with new application mode */
- DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed ApplicationMode."),
- DLT_STRING(" Old ApplicationMode: "), DLT_INT(NSM__enApplicationMode ),
- DLT_STRING(" New ApplicationMode: "), DLT_INT((gint) enApplicationMode));
+ DLT_LOG(NsmContext,
+ DLT_LOG_INFO,
+ DLT_STRING("NSM: Changed ApplicationMode.");
+ DLT_STRING("Old AppMode:"); DLT_INT((int) NSM__enNextApplicationMode);
+ DLT_STRING("New AppMode:"); DLT_INT((int) enApplicationMode));
+
+ NSM__enNextApplicationMode = enApplicationMode;
+
+ /* If original persistent value has not been read before, get it now! */
+ g_mutex_lock(NSM__pThisApplicationModeMutex);
- NSM__enApplicationMode = enApplicationMode;
+ if(NSM__boThisApplicationModeRead == FALSE)
+ {
+ /* Get data from persistence */
+ pcl_return = pclKeyReadData(NSM_PERS_APPLICATION_MODE_DB,
+ NSM_PERS_APPLICATION_MODE_KEY,
+ 0,
+ 0,
+ (unsigned char*) &NSM__enThisApplicationMode,
+ sizeof(NSM__enThisApplicationMode));
+
+ if(pcl_return != sizeof(NSM__enThisApplicationMode))
+ {
+ NSM__enThisApplicationMode = NsmApplicationMode_NotSet;
+ DLT_LOG(NsmContext,
+ DLT_LOG_WARN,
+ DLT_STRING("NSM: Failed to read ApplicationMode.");
+ DLT_STRING("Error: Unexpected PCL return.");
+ DLT_STRING("Return:"); DLT_INT(pcl_return));
+ }
+
+ NSM__boThisApplicationModeRead = TRUE;
+ }
+
+ g_mutex_unlock(NSM__pThisApplicationModeMutex);
+
+ /* Write the new application mode to persistence */
+ pcl_return = pclKeyWriteData(NSM_PERS_APPLICATION_MODE_DB,
+ NSM_PERS_APPLICATION_MODE_KEY,
+ 0,
+ 0,
+ (unsigned char*) &NSM__enNextApplicationMode,
+ sizeof(NSM__enNextApplicationMode));
+
+ if(pcl_return != sizeof(NSM__enNextApplicationMode))
+ {
+ DLT_LOG(NsmContext,
+ DLT_LOG_ERROR,
+ DLT_STRING("NSM: Failed to persist ApplicationMode.");
+ DLT_STRING("Error: Unexpected PCL return.");
+ DLT_STRING("Return:"); DLT_INT(pcl_return));
+ }
if(boInformBus == TRUE)
{
- NSMA_boSendApplicationModeSignal(NSM__enApplicationMode);
+ NSMA_boSendApplicationModeSignal(NSM__enNextApplicationMode);
}
if(boInformMachine == TRUE)
{
- NsmcSetData(NsmDataType_AppMode, (unsigned char*) &NSM__enApplicationMode, sizeof(NsmApplicationMode_e));
+ NsmcSetData(NsmDataType_AppMode,
+ (unsigned char*) &NSM__enNextApplicationMode,
+ sizeof(NsmApplicationMode_e));
}
}
- g_mutex_unlock(NSM__pApplicationModeMutex);
+ g_mutex_unlock(NSM__pNextApplicationModeMutex);
}
else
{
/* Error: The passed application mode is invalid. Return an error. */
enRetVal = NsmErrorStatus_Parameter;
- DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to change ApplicationMode. Invalid parameter." ),
- DLT_STRING(" Old ApplicationMode: "), DLT_INT(NSM__enApplicationMode ),
- DLT_STRING(" Desired ApplicationMode: "), DLT_INT((gint) enApplicationMode));
+ DLT_LOG(NsmContext,
+ DLT_LOG_ERROR,
+ DLT_STRING("NSM: Failed to change ApplicationMode.");
+ DLT_STRING("Error:"); DLT_STRING("Invalid parameter.");
+ DLT_STRING("Old AppMode:"); DLT_INT((int) NSM__enNextApplicationMode);
+ DLT_STRING("New AppMode:"); DLT_INT((int) enApplicationMode));
}
return enRetVal;
@@ -500,16 +704,47 @@ static NsmErrorStatus_e NSM__enSetApplicationMode(NsmApplicationMode_e enApplica
* @return see NsmApplicationMode_e
*
**********************************************************************************************************************/
-static NsmErrorStatus_e NSM__enGetApplicationMode(NsmApplicationMode_e *penApplicationMode)
+static NsmErrorStatus_e
+NSM__enGetApplicationMode(NsmApplicationMode_e *penApplicationMode)
{
- NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
+ NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
+ int pcl_return = 0;
if(penApplicationMode != NULL)
{
+ g_mutex_lock(NSM__pThisApplicationModeMutex);
+
+ /* Check if value already was obtained from persistence */
+ if(NSM__boThisApplicationModeRead == FALSE)
+ {
+ /* There was no read attempt before. Read from persistence */
+ pcl_return = pclKeyReadData(NSM_PERS_APPLICATION_MODE_DB,
+ NSM_PERS_APPLICATION_MODE_KEY,
+ 0,
+ 0,
+ (unsigned char*) &NSM__enThisApplicationMode,
+ sizeof(NSM__enThisApplicationMode));
+
+ /* Check the PCL return */
+ if(pcl_return != sizeof(NSM__enThisApplicationMode))
+ {
+ /* Read failed. From now on always return 'NsmApplicationMode_NotSet' */
+ NSM__enThisApplicationMode = NsmApplicationMode_NotSet;
+ DLT_LOG(NsmContext,
+ DLT_LOG_WARN,
+ DLT_STRING("NSM: Failed to read ApplicationMode.");
+ DLT_STRING("Error: Unexpected PCL return.");
+ DLT_STRING("Return:"); DLT_INT(pcl_return));
+ }
+
+ /* There was a first read attempt from persistence */
+ NSM__boThisApplicationModeRead = TRUE;
+ }
+
enRetVal = NsmErrorStatus_Ok;
- g_mutex_lock(NSM__pApplicationModeMutex);
- *penApplicationMode = NSM__enApplicationMode;
- g_mutex_unlock(NSM__pApplicationModeMutex);
+ *penApplicationMode = NSM__enThisApplicationMode;
+
+ g_mutex_unlock(NSM__pThisApplicationModeMutex);
}
else
{
@@ -1380,7 +1615,7 @@ static NsmErrorStatus_e NSM__enOnHandleRequestNodeRestart(const NsmRestartReason
DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Node restart has been requested."));
- if(NsmcRequestNodeRestart() == 0x01)
+ if(NsmcRequestNodeRestart(enRestartReason, u32RestartType) == 0x01)
{
enRetVal = NsmErrorStatus_Ok;
(void) NSMA_boSetRestartReason(enRestartReason);
@@ -1413,90 +1648,37 @@ static NsmErrorStatus_e NSM__enOnHandleRegisterSession(const gchar *
const NsmSessionState_e enSessionState)
{
/* Function local variables */
- NsmSession_s *pNewSession = NULL; /* Pointer to new created session */
- GSList *pListEntry = NULL; /* Pointer to list entry */
glong u32SessionNameLen = 0; /* Length of passed session owner */
glong u32SessionOwnerLen = 0; /* Length of passed session name */
- NsmSession_s stSearchSession = {0}; /* To search for existing session */
- gboolean boOwnerValid = FALSE;
+ NsmSession_s stSession; /* To search for existing session */
NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet;
/* Check if the passed parameters are valid */
u32SessionNameLen = g_utf8_strlen(sSessionName, -1);
u32SessionOwnerLen = g_utf8_strlen(sSessionOwner, -1);
- boOwnerValid = (g_strcmp0(sSessionOwner, NSM_DEFAULT_SESSION_OWNER) != 0);
- if( (boOwnerValid == TRUE )
- && (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH )
+ if( (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH )
&& (u32SessionOwnerLen < NSM_MAX_SESSION_OWNER_LENGTH)
&& (enSeatId > NsmSeat_NotSet )
- && (enSeatId < NsmSeat_Last )
- && (enSessionState > NsmSessionState_Unregistered))
+ && (enSeatId < NsmSeat_Last ))
{
/* Initialize temporary session object to check if session already exists */
- g_strlcpy((gchar*) stSearchSession.sName, sSessionName, sizeof(stSearchSession.sName) );
- g_strlcpy((gchar*) stSearchSession.sOwner, sSessionOwner, sizeof(stSearchSession.sOwner));
- stSearchSession.enSeat = enSeatId;
- stSearchSession.enState = enSessionState;
-
- if(NSM__boIsPlatformSession(&stSearchSession) == FALSE)
- {
- g_mutex_lock(NSM__pSessionMutex);
-
- pListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionNameSeatCompare);
-
- if(pListEntry == NULL)
- {
- enRetVal = NsmErrorStatus_Ok;
-
- pNewSession = g_new0(NsmSession_s, 1);
- memcpy(pNewSession, &stSearchSession, sizeof(NsmSession_s));
-
- DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Registered session." ),
- DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
- DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
- DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
- DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState));
-
- /* Return OK and append new object */
- NSM__pSessions = g_slist_append(NSM__pSessions, pNewSession);
-
- /* Inform D-Bus and StateMachine about the new session. */
- NSM__vPublishSessionChange(pNewSession, TRUE, TRUE);
- }
- else
- {
- /* Error: The session already exists. Don't store passed state. */
- enRetVal = NsmErrorStatus_WrongSession;
- DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to register session. Session already exists."),
- DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
- DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
- DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
- DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState ));
- }
+ g_strlcpy((gchar*) stSession.sName, sSessionName, sizeof(stSession.sName) );
+ g_strlcpy((gchar*) stSession.sOwner, sSessionOwner, sizeof(stSession.sOwner));
+ stSession.enSeat = enSeatId;
+ stSession.enState = enSessionState;
- g_mutex_unlock(NSM__pSessionMutex);
- }
- else
- {
- /* Error: It is not allowed to re-register a default session! */
- enRetVal = NsmErrorStatus_Parameter;
- DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to register session. Re-Registration of default session not allowed."),
- DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
- DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
- DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
- DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState ));
- }
+ enRetVal = NSM__enRegisterSession(&stSession, TRUE, TRUE);
}
else
{
/* Error: A parameter with an invalid value has been passed */
enRetVal = NsmErrorStatus_Parameter;
- DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to register session. 'Unregistered' not allowed."),
- DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
- DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
- DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ),
- DLT_STRING(" Initial state: "), DLT_INT((gint) enSessionState ));
+ DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to register session. Invalid parameter."),
+ DLT_STRING("Name:" ), DLT_STRING(sSessionName ),
+ DLT_STRING("Owner:" ), DLT_STRING(sSessionOwner ),
+ DLT_STRING("Seat:" ), DLT_INT((gint) enSeatId ),
+ DLT_STRING("Initial state:"), DLT_INT((gint) enSessionState ));
}
return enRetVal;
@@ -1520,8 +1702,6 @@ static NsmErrorStatus_e NSM__enOnHandleUnRegisterSession(const gchar *sSessi
const NsmSeat_e enSeatId)
{
/* Function local variables */
- NsmSession_s *pExistingSession = NULL; /* Pointer to existing session */
- GSList *pListEntry = NULL; /* Pointer to list entry */
glong u32SessionNameLen = 0; /* Length of passed session owner */
glong u32SessionOwnerLen = 0; /* Length of passed session name */
NsmSession_s stSearchSession = {0}; /* To search for existing session */
@@ -1539,54 +1719,7 @@ static NsmErrorStatus_e NSM__enOnHandleUnRegisterSession(const gchar *sSessi
g_strlcpy((gchar*) stSearchSession.sName, sSessionName, sizeof(stSearchSession.sName) );
g_strlcpy((gchar*) stSearchSession.sOwner, sSessionOwner, sizeof(stSearchSession.sOwner));
- if(NSM__boIsPlatformSession(&stSearchSession) == FALSE)
- {
- g_mutex_lock(NSM__pSessionMutex);
-
- pListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionOwnerNameSeatCompare);
-
- /* Check if the session exists */
- if(pListEntry != NULL)
- {
- /* Found the session in the list. Now remove it. */
- enRetVal = NsmErrorStatus_Ok;
- pExistingSession = (NsmSession_s*) pListEntry->data;
-
- DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Unregistered session." ),
- DLT_STRING(" Name: " ), DLT_STRING(pExistingSession->sName ),
- DLT_STRING(" Owner: " ), DLT_STRING(pExistingSession->sOwner ),
- DLT_STRING(" Seat: " ), DLT_INT( pExistingSession->enSeat ),
- DLT_STRING(" Last state: "), DLT_INT( pExistingSession->enState));
-
- pExistingSession->enState = NsmSessionState_Unregistered;
-
- /* Inform D-Bus and StateMachine about the unregistered session */
- NSM__vPublishSessionChange(pExistingSession, TRUE, TRUE);
-
- NSM__vFreeSessionObject(pExistingSession);
- NSM__pSessions = g_slist_remove(NSM__pSessions, pExistingSession);
- }
- else
- {
- /* Error: The session is unknown. */
- enRetVal = NsmErrorStatus_WrongSession;
- DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to unregister session. Session unknown."),
- DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
- DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
- DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ));
- }
-
- g_mutex_unlock(NSM__pSessionMutex);
- }
- else
- {
- /* Error: Failed to unregister session. The passed session is a "platform" session. */
- enRetVal = NsmErrorStatus_WrongSession;
- DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to unregister session. The session is a platform session."),
- DLT_STRING(" Name: " ), DLT_STRING(sSessionName ),
- DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ),
- DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId ));
- }
+ enRetVal = NSM__enUnRegisterSession(&stSearchSession, TRUE, TRUE);
}
else
{
@@ -2093,6 +2226,66 @@ static guint NSM__u32OnHandleGetInterfaceVersion(void)
/**********************************************************************************************************************
*
+* The function is called cyclically and triggers the systemd wdog.
+*
+* @param pUserData: Pointer to optional user data
+*
+* @return Always TRUE to keep timer callback alive.
+*
+**********************************************************************************************************************/
+static gboolean NSM__boOnHandleTimerWdog(gpointer pUserData)
+{
+ (void) sd_notify(0, "WATCHDOG=1");
+ DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Triggered systemd WDOG."));
+
+ return TRUE;
+}
+
+
+/**********************************************************************************************************************
+*
+* The function checks if the NSM is observed by a systemd wdog and installs a timer if necessary.
+*
+**********************************************************************************************************************/
+static void NSM__vConfigureWdogTimer(void)
+{
+ const gchar *sWdogSec = NULL;
+ guint u32WdogSec = 0;
+
+ sWdogSec = g_getenv("WATCHDOG_USEC");
+
+ if(sWdogSec != NULL)
+ {
+ u32WdogSec = strtoul(sWdogSec, NULL, 10);
+
+ /* The min. valid value for systemd is 1 s => WATCHDOG_USEC at least needs to contain 1.000.000 us */
+ if(u32WdogSec >= 1000000)
+ {
+ /* Convert us timeout in ms and divide by two to trigger wdog every half timeout interval */
+ u32WdogSec /= 2000;
+ (void) g_timeout_add_full(G_PRIORITY_DEFAULT,
+ u32WdogSec,
+ &NSM__boOnHandleTimerWdog,
+ NULL,
+ NULL);
+ DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Started wdog timer." ),
+ DLT_STRING("Interval [ms]:"), DLT_UINT(u32WdogSec));
+ }
+ else
+ {
+ DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Error. Invalid wdog config." ),
+ DLT_STRING("WATCHDOG_USEC:"), DLT_STRING(sWdogSec));
+ }
+ }
+ else
+ {
+ DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Daemon not observed by wdog"));
+ }
+}
+
+
+/**********************************************************************************************************************
+*
* The function initializes all file local variables
*
**********************************************************************************************************************/
@@ -2104,10 +2297,13 @@ static void NSM__vInitializeVariables(void)
NSM__pLifecycleClients = NULL;
NSM__pNodeStateMutex = NULL;
NSM__enNodeState = NsmNodeState_NotSet;
- NSM__pApplicationModeMutex = NULL;
- NSM__enApplicationMode = NsmApplicationMode_NotSet;
+ NSM__pNextApplicationModeMutex = NULL;
+ NSM__pThisApplicationModeMutex = NULL;
NSM__pFailedApplications = NULL;
NSM__pCurrentLifecycleClient = NULL;
+ NSM__enNextApplicationMode = NsmApplicationMode_NotSet;
+ NSM__enThisApplicationMode = NsmApplicationMode_NotSet;
+ NSM__boThisApplicationModeRead = FALSE;
}
@@ -2151,7 +2347,8 @@ static void NSM__vCreateMutexes(void)
{
/* Initialize the local mutexes */
NSM__pNodeStateMutex = g_mutex_new();
- NSM__pApplicationModeMutex = g_mutex_new();
+ NSM__pThisApplicationModeMutex = g_mutex_new();
+ NSM__pNextApplicationModeMutex = g_mutex_new();
NSM__pSessionMutex = g_mutex_new();
}
@@ -2165,7 +2362,8 @@ static void NSM__vDeleteMutexes(void)
{
/* Delete the local mutexes */
g_mutex_free(NSM__pNodeStateMutex);
- g_mutex_free(NSM__pApplicationModeMutex);
+ g_mutex_free(NSM__pNextApplicationModeMutex);
+ g_mutex_free(NSM__pThisApplicationModeMutex);
g_mutex_free(NSM__pSessionMutex);
}
@@ -2277,6 +2475,20 @@ NsmErrorStatus_e NsmSetData(NsmDataType_e enData, unsigned char *pData, unsigned
: NsmErrorStatus_Parameter;
break;
+ /* NSMC wants to register a session */
+ case NsmDataType_RegisterSession:
+ enRetVal = (u32DataLen == sizeof(NsmSession_s))
+ ? NSM__enRegisterSession((NsmSession_s*) pData, TRUE, FALSE)
+ : NsmErrorStatus_Parameter;
+ break;
+
+ /* NSMC wants to unregister a session */
+ case NsmDataType_UnRegisterSession:
+ enRetVal = (u32DataLen == sizeof(NsmSession_s))
+ ? NSM__enUnRegisterSession((NsmSession_s*) pData, TRUE, FALSE)
+ : NsmErrorStatus_Parameter;
+ break;
+
/* Error: The type of the data NSMC is trying to set is unknown or the data is read only! */
case NsmDataType_RestartReason:
case NsmDataType_RunningReason:
@@ -2395,7 +2607,8 @@ unsigned int NsmGetInterfaceVersion(void)
/* The main function of the NodeStateManager */
int main(void)
{
- gboolean boEndByUser = FALSE;
+ gboolean boEndByUser = FALSE;
+ int pcl_return = 0;
/* Initialize glib for using "g" types */
g_type_init();
@@ -2409,7 +2622,19 @@ int main(void)
NSM__vSyslogOpen();
/* Print first msg. to show that NSM is going to start */
- DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: NodeStateManager started."));
+ DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: NodeStateManager started."), DLT_STRING("Version:"), DLT_STRING(VERSION));
+
+ /* Initialize PCL before initializing variables */
+ pcl_return = pclInitLibrary("NodeStateManager", PCL_SHUTDOWN_TYPE_NORMAL
+ | PCL_SHUTDOWN_TYPE_FAST);
+ if(pcl_return < 0)
+ {
+ DLT_LOG(NsmContext,
+ DLT_LOG_WARN,
+ DLT_STRING("NSM: Failed to initialize PCL.");
+ DLT_STRING("Error: Unexpected PCL return.");
+ DLT_STRING("Return:"); DLT_INT(pcl_return));
+ }
/* Currently no other resources accessing the NSM. Prepare it now! */
NSM__vInitializeVariables(); /* Initialize file local variables*/
@@ -2428,6 +2653,9 @@ int main(void)
/* Initialize/start the NSMC */
if(NsmcInit() == 0x01)
{
+ /* Start timer to satisfy wdog */
+ NSM__vConfigureWdogTimer();
+
/* The event loop is only canceled if the Node is completely shut down or there is an internal error. */
boEndByUser = NSMA_boWaitForEvents();
@@ -2466,6 +2694,18 @@ int main(void)
g_slist_free_full(NSM__pFailedApplications, &NSM__vFreeFailedApplicationObject);
g_list_free_full (NSM__pLifecycleClients, &NSM__vFreeLifecycleClientObject);
+ /* Deinitialize the PCL */
+ pcl_return = pclDeinitLibrary();
+
+ if(pcl_return < 0)
+ {
+ DLT_LOG(NsmContext,
+ DLT_LOG_WARN,
+ DLT_STRING("NSM: Failed to deinitialize PCL.");
+ DLT_STRING("Error: Unexpected PCL return.");
+ DLT_STRING("Return:"); DLT_INT(pcl_return));
+ }
+
DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: NodeStateManager stopped."));
/* Deinit syslog */
diff --git a/NodeStateManager/NodeStateManager.h b/NodeStateManager/NodeStateManager.h
index 61b9995..522fe3e 100644
--- a/NodeStateManager/NodeStateManager.h
+++ b/NodeStateManager/NodeStateManager.h
@@ -18,12 +18,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Date Author Reason
-* 2012.06.01 uidu5846 1.0.0.0 CSP_WZ#388: Initial version of the NodeStateManager interface
-* 2012.09.27 uidu5846 1.1.0.0 CSP_WZ#1194: Changed file header structure and license to be released
-* as open source package. Introduced 'NodeStateTypes.h' to
-* avoid circle includes and encapsulate type definitions.
-* 2012.10.24 uidu5846 1.2.0.0 CSP_WZ#1322: Changed types of interface parameters to native types.
-* Since the same native types are used, no interface change.
+* 2012.06.01 uidu5846 1.0.0.0 CSP_WZ#388: Initial version of the NodeStateManager interface
+* 2012.09.27 uidu5846 1.1.0.0 CSP_WZ#1194: Changed file header structure and license to be released
+* as open source package. Introduced 'NodeStateTypes.h' to
+* avoid circle includes and encapsulate type definitions.
+* 2012.10.24 uidu5846 1.2.0.0 CSP_WZ#1322: Changed types of interface parameters to native types.
+* Since the same native types are used, no interface change.
+* 2013.04.18 uidu5846 1.2.1 OvipRbt#1153: Increased minor version number.
*
**********************************************************************************************************************/
@@ -59,7 +60,7 @@ extern "C"
* The lower significant byte is equal 0 for released version only
*/
-#define NSM_INTERFACE_VERSION 0x01020000U
+#define NSM_INTERFACE_VERSION 0x01020100U
/**********************************************************************************************************************
*
diff --git a/NodeStateManager/NodeStateTypes.h b/NodeStateManager/NodeStateTypes.h
index 023dfa9..7451a19 100644
--- a/NodeStateManager/NodeStateTypes.h
+++ b/NodeStateManager/NodeStateTypes.h
@@ -20,6 +20,7 @@
* and encapsulate type definitions.
* 2012.10.24 uidu5846 1.0.0.1 CSP_WZ#1322: Removed "ssw_types" redefinition from header.
* Since the same native types are used, no interface change.
+* 2013.04.18 uidu5846 1.2.1 OvipRbt#1153 Added possibility to register sessions via the NSMC.
*
**********************************************************************************************************************/
@@ -87,7 +88,9 @@ typedef enum _NsmDataType_e
NsmDataType_SessionState, /**< A SessionState should be set or get */
NsmDataType_ShutdownReason, /**< A ShutdownReason should be set or get */
NsmDataType_BootMode, /**< A BootMode should be set or get */
- NsmDataType_RunningReason /**< A RunningReason should be set or get */
+ NsmDataType_RunningReason, /**< A RunningReason should be set or get */
+ NsmDataType_RegisterSession, /**< A Session should be registered */
+ NsmDataType_UnRegisterSession /**< A Session should be unregistered */
} NsmDataType_e;
diff --git a/NodeStateManager/config/node-state-manager.pc.in b/NodeStateManager/config/node-state-manager.pc.in
index 480ff5d..11fb8df 100644
--- a/NodeStateManager/config/node-state-manager.pc.in
+++ b/NodeStateManager/config/node-state-manager.pc.in
@@ -4,7 +4,7 @@ prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-dbusinterfacesdir=@dbusinterfacesdir@
+dbusinterfacesdir=${pc_sysrootdir}@dbusinterfacesdir@
Name: NodeStateManager (NSM)
Description: Package information for the NHM.
diff --git a/NodeStateManager/config/nodestatemanager-daemon.service.in b/NodeStateManager/config/nodestatemanager-daemon.service.in
index 6842cbd..71fcc3c 100644
--- a/NodeStateManager/config/nodestatemanager-daemon.service.in
+++ b/NodeStateManager/config/nodestatemanager-daemon.service.in
@@ -11,13 +11,17 @@
[Unit]
Description=NodeStateManager to provide system states, session and shutdown handling
-Wants=dbus.service dlt-daemon.service
-After=dbus.service dlt-daemon.service
+Wants=dbus.service dlt-daemon.service pas-daemon.service
+After=dbus.service dlt-daemon.service pas-daemon.service
# Start up very early, because it doesn't need anything to run prior to it:
DefaultDependencies=no
[Service]
+Type=dbus
+WatchdogSec=20
+NotifyAccess=main
+BusName=org.genivi.NodeStateManager
ExecStart=/usr/bin/NodeStateManager
[Install]
diff --git a/NodeStateTest/NodeStateTest.c b/NodeStateTest/NodeStateTest.c
index 980e8d0..75060dd 100644
--- a/NodeStateTest/NodeStateTest.c
+++ b/NodeStateTest/NodeStateTest.c
@@ -35,7 +35,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Date Author Reason
-* 24.01.2013 Jean-Pierre Bogler CSP_WZ#1194: Initial creation.
+* 24.01.2013 Jean-Pierre Bogler CSP_WZ#1194: Initial creation.
+* 18.04.2013 Jean-Pierre Bogler OvipRbt#1153: Implemented test cases 164 - 170.
*
**********************************************************************************************************************/
@@ -140,7 +141,9 @@ typedef struct
{
guint u32DataLen; /* Length of the data to be set in byte */
NsmSession_s stSession; /* Defines session and state that should be set */
-} NSMTST__tstSmSetSessionStateParam;
+} NSMTST__tstSmSetSessionStateParam,
+ NSMTST__tstSmRegisterSessionParam,
+ NSMTST__tstSmUnRegisterSessionParam;
/* Configure the parameters for setting a ShutdownReason using the (internal) NsmSetData interface. */
typedef struct
@@ -293,6 +296,8 @@ typedef union
NSMTST__tstSmSetApplicationModeParam stSmSetApplicationMode;
NSMTST__tstSmSetNodeStateParam stSmSetNodeState;
NSMTST__tstSmSetSessionStateParam stSmSetSessionState;
+ NSMTST__tstSmRegisterSessionParam stSmRegisterSession;
+ NSMTST__tstSmUnRegisterSessionParam stSmUnRegisterSession;
NSMTST__tstSmSetShutdownReasonParam stSmSetShutdownReason;
NSMTST__tstSmSetBootModeParam stSmSetBootMode;
@@ -455,6 +460,8 @@ typedef struct
NSMTST__tstSmSetInvalidDataReturn,
NSMTST__tstSmSetShutdownModeReturn,
NSMTST__tstSmSetSessionStateReturn,
+ NSMTST__tstSmRegisterSessionReturn,
+ NSMTST__tstSmUnRegisterSessionReturn,
NSMTST__tstTestLifecycleRequestCompleteReturn;
/* Configures the expected values for the reception of the SessionState signal send by the NSM. */
@@ -525,6 +532,8 @@ typedef union
NSMTST__tstSmSetApplicationModeReturn stSmSetApplicationMode;
NSMTST__tstSmSetInvalidDataReturn stSmSetInvalidData;
NSMTST__tstSmSetSessionStateReturn stSmSetSessionState;
+ NSMTST__tstSmRegisterSessionReturn stSmRegisterSession;
+ NSMTST__tstSmUnRegisterSessionReturn stSmUnRegisterSession;
NSMTST__tstSmGetAppModeReturn stSmGetApplicationMode;
NSMTST__tstSmGetNodeStateReturn stSmGetNodeState;
@@ -596,6 +605,8 @@ static gboolean NSMTST__boDbLifecycleRequestComplete (void);
static gboolean NSMTST__boSmSetApplicationMode (void);
static gboolean NSMTST__boSmSetNodeState (void);
static gboolean NSMTST__boSmSetSessionState (void);
+static gboolean NSMTST__boSmRegisterSession (void);
+static gboolean NSMTST__boSmUnRegisterSession (void);
static gboolean NSMTST__boSmSetShutdownReason (void);
static gboolean NSMTST__boSmSetBootMode (void);
static gboolean NSMTST__boSmSetInvalidData (void);
@@ -842,6 +853,17 @@ static NSMTST__tstTestCase NSMTST__astTestCases[] =
{ &NSMTST__boTestProcessLifecycleRequest, .unParameter.stTestProcessLifecycleRequest = {NsmErrorStatus_Ok}, .unReturnValues.stTestProcessLifecycleRequest = {NSM_SHUTDOWNTYPE_FAST} },
{ &NSMTST__boTestProcessLifecycleRequest, .unParameter.stTestProcessLifecycleRequest = {NsmErrorStatus_Ok}, .unReturnValues.stTestProcessLifecycleRequest = {NSM_SHUTDOWNTYPE_RUNUP} },
{ &NSMTST__boTestProcessLifecycleRequest, .unParameter.stTestProcessLifecycleRequest = {NsmErrorStatus_Ok}, .unReturnValues.stTestProcessLifecycleRequest = {NSM_SHUTDOWNTYPE_RUNUP} },
+ { &NSMTST__boDbSetSessionState, .unParameter.stDbSetSessionState = {"PlatformSupplySession", "NodeStateTest", NsmSeat_Driver, (NsmSessionState_e) 0x02}, .unReturnValues.stDbSetSessionState = {NsmErrorStatus_Ok} },
+ { &NSMTST__boDbGetSessionState, .unParameter.stDbGetSessionState = {"PlatformSupplySession", NsmSeat_Driver}, .unReturnValues.stDbGetSessionState = {NsmErrorStatus_Ok, (NsmSessionState_e) 0x02} },
+ { &NSMTST__boDbSetSessionState, .unParameter.stDbSetSessionState = {"PlatformSupplySession", "NodeStateTest", NsmSeat_Driver, (NsmSessionState_e) 0x03}, .unReturnValues.stDbSetSessionState = {NsmErrorStatus_Ok} },
+ { &NSMTST__boCheckSessionSignal, .unParameter.stTestDummy = {0x00}, .unReturnValues.stCheckSessionSignal = {TRUE, "PlatformSupplySession", NsmSeat_Driver, (NsmSessionState_e) 0x03 } },
+ { &NSMTST__boDbGetSessionState, .unParameter.stDbGetSessionState = {"PlatformSupplySession", NsmSeat_Driver}, .unReturnValues.stDbGetSessionState = {NsmErrorStatus_Ok, (NsmSessionState_e) 0x03} },
+ { &NSMTST__boSmRegisterSession, .unParameter.stSmRegisterSession = {sizeof(NsmSession_s), {"StateMachine", "NodeStateTest", NsmSeat_Driver, NsmSessionState_Active}}, .unReturnValues.stSmRegisterSession = {NsmErrorStatus_Ok} },
+ { &NSMTST__boCheckSessionSignal, .unParameter.stTestDummy = {0x00}, .unReturnValues.stCheckSessionSignal = {TRUE, "StateMachine", NsmSeat_Driver, NsmSessionState_Active } },
+ { &NSMTST__boSmRegisterSession, .unParameter.stSmRegisterSession = {sizeof(NsmSession_s)-1, {"StateMachine", "NodeStateTest", NsmSeat_Driver, NsmSessionState_Active}}, .unReturnValues.stSmRegisterSession = {NsmErrorStatus_Parameter} },
+ { &NSMTST__boSmUnRegisterSession, .unParameter.stSmUnRegisterSession = {sizeof(NsmSession_s)-1, {"StateMachine", "NodeStateTest", NsmSeat_Driver, NsmSessionState_Active}}, .unReturnValues.stSmRegisterSession = {NsmErrorStatus_Parameter} },
+ { &NSMTST__boSmUnRegisterSession, .unParameter.stSmUnRegisterSession = {sizeof(NsmSession_s), {"StateMachine", "NodeStateTest", NsmSeat_Driver, NsmSessionState_Unregistered}}, .unReturnValues.stSmRegisterSession = {NsmErrorStatus_Ok} },
+ { &NSMTST__boCheckSessionSignal, .unParameter.stTestDummy = {0x00}, .unReturnValues.stCheckSessionSignal = {TRUE, "StateMachine", NsmSeat_Driver, NsmSessionState_Unregistered } }
};
@@ -2141,6 +2163,128 @@ static gboolean NSMTST__boSmSetSessionState(void)
return boRetVal;
}
+
+static gboolean NSMTST__boSmRegisterSession(void)
+{
+ /* Function local variables */
+ gboolean boRetVal = TRUE; /* Return value */
+ GError *pError = NULL;
+ GVariant *pDataIn = NULL;
+ NsmErrorStatus_e enReceivedNsmReturn = NsmErrorStatus_NotSet;
+
+ /* Values read from parameter config */
+ const guint u32DataLen = NSMTST__pstTestCase->unParameter.stSmRegisterSession.u32DataLen;
+ const NsmSession_s stSession = NSMTST__pstTestCase->unParameter.stSmRegisterSession.stSession;
+
+ /* Values read from return config */
+ const NsmErrorStatus_e enExpectedNsmReturn = NSMTST__pstTestCase->unReturnValues.stSmRegisterSession.enErrorStatus;
+
+ /* Variables need to adapt test case */
+ const gchar *sNsmValue = "RegisterSession";
+ const NsmDataType_e enDataType = NsmDataType_RegisterSession;
+ const guint u32RealDataLen = sizeof(NsmSession_s);
+
+ /* Create test case description */
+ NSMTST__sTestDescription = g_strdup_printf("Set %s. Interface: StateMachine. Passed DataLen: %d.",
+ sNsmValue, u32DataLen);
+ /* Perform test call */
+ pDataIn = NSMTST__pPrepareStateMachineData((guchar*) &stSession, u32RealDataLen);
+ (void) node_state_test_call_set_nsm_data_sync(NSMTST__pNodeStateMachine,
+ enDataType,
+ pDataIn,
+ u32DataLen,
+ (gint*) &enReceivedNsmReturn,
+ NULL,
+ &pError);
+ g_variant_unref(pDataIn);
+
+ /* Evaluate result. Check if a D-Bus error occurred. */
+ if(pError == NULL)
+ {
+ /* D-Bus communication successful. Check if NSM returned with the expected value. */
+ if(enReceivedNsmReturn == enExpectedNsmReturn)
+ {
+ boRetVal = TRUE;
+ }
+ else
+ {
+ boRetVal = FALSE;
+ NSMTST__sErrorDescription = g_strdup_printf("Did not receive expected NSM return value. Received: 0x%02X. Expected: 0x%02X.",
+ enReceivedNsmReturn, enExpectedNsmReturn);
+ }
+ }
+ else
+ {
+ boRetVal = FALSE;
+ NSMTST__sErrorDescription = g_strdup_printf("Failed to create access NSMC via D-Bus. Error msg.: %s.",
+ pError->message);
+ g_error_free(pError);
+ }
+
+ return boRetVal;
+}
+
+static gboolean NSMTST__boSmUnRegisterSession(void)
+{
+ /* Function local variables */
+ gboolean boRetVal = TRUE; /* Return value */
+ GError *pError = NULL;
+ GVariant *pDataIn = NULL;
+ NsmErrorStatus_e enReceivedNsmReturn = NsmErrorStatus_NotSet;
+
+ /* Values read from parameter config */
+ const guint u32DataLen = NSMTST__pstTestCase->unParameter.stSmUnRegisterSession.u32DataLen;
+ const NsmSession_s stSession = NSMTST__pstTestCase->unParameter.stSmUnRegisterSession.stSession;
+
+ /* Values read from return config */
+ const NsmErrorStatus_e enExpectedNsmReturn = NSMTST__pstTestCase->unReturnValues.stSmUnRegisterSession.enErrorStatus;
+
+ /* Variables need to adapt test case */
+ const gchar *sNsmValue = "UnRegisterSession";
+ const NsmDataType_e enDataType = NsmDataType_UnRegisterSession;
+ const guint u32RealDataLen = sizeof(NsmSession_s);
+
+ /* Create test case description */
+ NSMTST__sTestDescription = g_strdup_printf("Set %s. Interface: StateMachine. Passed DataLen: %d.",
+ sNsmValue, u32DataLen);
+ /* Perform test call */
+ pDataIn = NSMTST__pPrepareStateMachineData((guchar*) &stSession, u32RealDataLen);
+ (void) node_state_test_call_set_nsm_data_sync(NSMTST__pNodeStateMachine,
+ enDataType,
+ pDataIn,
+ u32DataLen,
+ (gint*) &enReceivedNsmReturn,
+ NULL,
+ &pError);
+ g_variant_unref(pDataIn);
+
+ /* Evaluate result. Check if a D-Bus error occurred. */
+ if(pError == NULL)
+ {
+ /* D-Bus communication successful. Check if NSM returned with the expected value. */
+ if(enReceivedNsmReturn == enExpectedNsmReturn)
+ {
+ boRetVal = TRUE;
+ }
+ else
+ {
+ boRetVal = FALSE;
+ NSMTST__sErrorDescription = g_strdup_printf("Did not receive expected NSM return value. Received: 0x%02X. Expected: 0x%02X.",
+ enReceivedNsmReturn, enExpectedNsmReturn);
+ }
+ }
+ else
+ {
+ boRetVal = FALSE;
+ NSMTST__sErrorDescription = g_strdup_printf("Failed to create access NSMC via D-Bus. Error msg.: %s.",
+ pError->message);
+ g_error_free(pError);
+ }
+
+ return boRetVal;
+}
+
+
static gboolean NSMTST__boSmSetShutdownReason(void)
{
/* Function local variables */
diff --git a/configure.ac b/configure.ac
index 913c4a7..a094b4e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,14 +12,10 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
-# Date Author Reason
-# 24.01.2013 Jean-Pierre Bogler Added NodeStateTest/Makefile to output files
-# 14.03.2013 Jean-Pierre Bogler Updated usage for real NodeStateAccess library
-#
#######################################################################################################################
# Initialize autoconf
-AC_INIT([node-state-manager],[1.2.0.0])
+AC_INIT([node-state-manager],[1.3.5])
AC_COPYRIGHT([Copyright (c) 2012 Continental Automotive GmbH])
AC_PREREQ([2.50])
@@ -42,12 +38,14 @@ AC_CHECK_HEADERS([string.h])
AC_CHECK_FUNCS([memcpy])
# Check for required packages
-PKG_CHECK_MODULES([DLT], [automotive-dlt >= 2.2.0] )
-PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.30.0] )
-PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.30.0] )
-PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.30.0] )
-PKG_CHECK_MODULES([GOBJECT], [gobject-2.0 >= 2.30.0] )
-PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.4.10] )
+PKG_CHECK_MODULES([DLT], [automotive-dlt >= 2.2.0 ])
+PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.30.0])
+PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.30.0])
+PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.30.0])
+PKG_CHECK_MODULES([GOBJECT], [gobject-2.0 >= 2.30.0])
+PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.4.10])
+PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon >= 37 ])
+PKG_CHECK_MODULES([PCL], [persistence_client_library >= 0.6.0 ])
# Derive path for storing systemd service files (e. g. /lib/systemd/system)
AC_ARG_WITH([systemdsystemunitdir],