From 4e48024924d9441cc4431b26bf6e1c9d1f3697e8 Mon Sep 17 00:00:00 2001 From: Bogler Date: Fri, 7 Dec 2012 15:28:10 +0100 Subject: Initial commit of Node State Manager --- AUTHORS | 2 + COPYING | 373 +++ ChangeLog | 0 Makefile.am | 19 + NEWS | 5 + NodeStateAccessStub/Makefile.am | 27 + NodeStateAccessStub/NodeStateAccess.c | 189 ++ NodeStateAccessStub/NodeStateAccess.h | 378 +++ .../model/org.genivi.NodeStateManager.Consumer.xml | 235 ++ ...g.genivi.NodeStateManager.LifecycleConsumer.xml | 23 + ...rg.genivi.NodeStateManager.LifecycleControl.xml | 87 + NodeStateMachineStub/Makefile.am | 23 + NodeStateMachineStub/NodeStateMachine.c | 114 + NodeStateMachineStub/NodeStateMachine.h | 135 ++ NodeStateManager/Makefile.am | 55 + NodeStateManager/NodeStateManager.c | 2494 ++++++++++++++++++++ NodeStateManager/NodeStateManager.h | 129 + NodeStateManager/NodeStateTypes.h | 252 ++ .../config/nodestatemanager-daemon.service.in | 15 + ...vi.NodeStateManager.LifeCycleControl.service.in | 4 + .../config/org.genivi.NodeStateManager.conf | 21 + README | 32 + autogen.sh | 3 + configure.ac | 87 + 24 files changed, 4702 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 NodeStateAccessStub/Makefile.am create mode 100644 NodeStateAccessStub/NodeStateAccess.c create mode 100644 NodeStateAccessStub/NodeStateAccess.h create mode 100644 NodeStateAccessStub/model/org.genivi.NodeStateManager.Consumer.xml create mode 100644 NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleConsumer.xml create mode 100644 NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleControl.xml create mode 100644 NodeStateMachineStub/Makefile.am create mode 100644 NodeStateMachineStub/NodeStateMachine.c create mode 100644 NodeStateMachineStub/NodeStateMachine.h create mode 100644 NodeStateManager/Makefile.am create mode 100644 NodeStateManager/NodeStateManager.c create mode 100644 NodeStateManager/NodeStateManager.h create mode 100644 NodeStateManager/NodeStateTypes.h create mode 100644 NodeStateManager/config/nodestatemanager-daemon.service.in create mode 100644 NodeStateManager/config/org.genivi.NodeStateManager.LifeCycleControl.service.in create mode 100644 NodeStateManager/config/org.genivi.NodeStateManager.conf create mode 100644 README create mode 100755 autogen.sh create mode 100644 configure.ac diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..62bf195 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Jean-Pierre Bogler +Christian Domke diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..14e2f77 --- /dev/null +++ b/COPYING @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + 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/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5a485fe --- /dev/null +++ b/Makefile.am @@ -0,0 +1,19 @@ +####################################################################################################################### +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Jean-Pierre.Bogler@continental-corporation.com +# +# Makefile template for the NodeStateManager +# +# Process this file with automake to produce a Makefile.in. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# 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/. +# +####################################################################################################################### + +SUBDIRS = NodeStateAccessStub NodeStateMachineStub NodeStateManager + + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..24338f9 --- /dev/null +++ b/NEWS @@ -0,0 +1,5 @@ +0.1.0 +===== +* Initial release of the NodeStateManager +* Stubs used for NodeStateMAchine and NodeStateAccess +* D-Bus interface wrappers, because of legal concerns diff --git a/NodeStateAccessStub/Makefile.am b/NodeStateAccessStub/Makefile.am new file mode 100644 index 0000000..58e190e --- /dev/null +++ b/NodeStateAccessStub/Makefile.am @@ -0,0 +1,27 @@ +####################################################################################################################### +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Jean-Pierre.Bogler@continental-corporation.com +# +# Makefile template for the NodeStateMachineStub +# +# Process this file with automake to produce a Makefile.in. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# 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/. +# +####################################################################################################################### + +noinst_LTLIBRARIES = libNodeStateAccess.la + +libNodeStateAccess_la_CFLAGS = \ + -I$(top_srcdir)/NodeStateManager \ + $(GIO_CFLAGS) \ + $(GIO_UNIX_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GOBJECT_CFLAGS) \ + $(PLATFORM_CFLAGS) + +libNodeStateAccess_la_SOURCES = NodeStateAccess.c NodeStateAccess.h diff --git a/NodeStateAccessStub/NodeStateAccess.c b/NodeStateAccessStub/NodeStateAccess.c new file mode 100644 index 0000000..7e1fbc0 --- /dev/null +++ b/NodeStateAccessStub/NodeStateAccess.c @@ -0,0 +1,189 @@ +/********************************************************************************************************************** +* +* Copyright (C) 2012 Continental Automotive Systems, Inc. +* +* Author: Jean-Pierre.Bogler@continental-corporation.com +* +* Interface between NodeStateManager and IPC +* +* This source file is a part of the NodeStateAccess library (NSMA) stub. +* The architecture requires that the NodeStateManager (NSM) is independent +* from the D-Bus binding and generated code. The interface functions of the +* library have to be implemented according to their description. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* 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 +* +**********************************************************************************************************************/ + + +/********************************************************************************************************************** +* +* Header includes +* +**********************************************************************************************************************/ + +/* generic includes for the NodeStateAccess library */ +#include "gio/gio.h" /* glib types */ +#include "NodeStateAccess.h" /* own header */ +#include "NodeStateTypes.h" /* Type defintions of the NSM */ + +/* additional includes to use D-Bus */ + + + +/********************************************************************************************************************** +* +* Local variables +* +**********************************************************************************************************************/ + +/* Variables to handle main loop and bus connection */ + + +/********************************************************************************************************************** +* +* Prototypes for file local functions (see implementation for description) +* +**********************************************************************************************************************/ + + +/********************************************************************************************************************** +* +* Local (static) functions +* +**********************************************************************************************************************/ + + +/********************************************************************************************************************** +* +* Interfaces. Exported functions. See Header for detailed description. +* +**********************************************************************************************************************/ + +gboolean NSMA_boInit(const NSMA_tstObjectCallbacks *pstCallbacks) +{ + return FALSE; +} + + +gboolean NSMA_boWaitForEvents(void) +{ + return FALSE; +} + + +gboolean NSMA_boSendNodeStateSignal(const NsmNodeState_e enNodeState) +{ + return FALSE; +} + + +gboolean NSMA_boSendSessionSignal(const NsmSession_s *pstSession) +{ + return FALSE; +} + + +gboolean NSMA_boSendApplicationModeSignal(const NsmApplicationMode_e enApplicationMode) +{ + return FALSE; +} + + +gboolean NSMA_boSetBootMode(gint i32BootMode) +{ + return FALSE; +} + + +gboolean NSMA_boGetBootMode(gint *pi32BootMode) +{ + return FALSE; +} + + +gboolean NSMA_boSetRunningReason(const NsmRunningReason_e enRunningReason) +{ + return FALSE; +} + + +gboolean NSMA_boGetRunningReason(NsmRunningReason_e *penRunningReason) +{ + return FALSE; +} + + +gboolean NSMA_boSetShutdownReason(const NsmShutdownReason_e enShutdownReason) +{ + return FALSE; +} + + +gboolean NSMA_boGetShutdownReason(NsmShutdownReason_e *penShutdownReason) +{ + return FALSE; +} + + +gboolean NSMA_boSetRestartReason(const NsmRestartReason_e enRestartReason) +{ + return FALSE; +} + + +gboolean NSMA_boGetRestartReason(NsmRestartReason_e *penRestartReason) +{ + return FALSE; +} + + +gboolean NSMA_boQuitEventLoop(void) +{ + return FALSE; +} + + +gboolean NSMA_boFreeLcConsumerProxy(NSMA_tLcConsumerHandle hLcConsumer) +{ + return FALSE; +} + + +NSMA_tLcConsumerHandle NSMA_hCreateLcConsumer(const gchar* sBusName, + const gchar* sObjName, + const guint u32TimeoutMs) +{ + return NULL; +} + + + +gboolean NSMA_boCallLcClientRequest(NSMA_tLcConsumerHandle hLcClient, + guint u32ShutdownType) +{ + return FALSE; +} + + +gboolean NSMA_boSetLcClientTimeout(NSMA_tLcConsumerHandle hClient, guint u32TimeoutMs) +{ + return FALSE; +} + + +gboolean NSMA_boGetLcClientTimeout(NSMA_tLcConsumerHandle hClient, guint *pu32TimeoutMs) +{ + return FALSE; +} + + +gboolean NSMA_boDeInit(void) +{ + return FALSE; +} diff --git a/NodeStateAccessStub/NodeStateAccess.h b/NodeStateAccessStub/NodeStateAccess.h new file mode 100644 index 0000000..96beb25 --- /dev/null +++ b/NodeStateAccessStub/NodeStateAccess.h @@ -0,0 +1,378 @@ +#ifndef NODESTATEACCESS_H_ +#define NODESTATEACCESS_H_ + +/********************************************************************************************************************** +* +* Copyright (C) 2012 Continental Automotive Systems, Inc. +* +* Author: Jean-Pierre.Bogler@continental-corporation.com +* +* Interface between NodeStateManager and IPC +* +* This header file is a part of the NodeStateAccess library (NSMA) stub. +* The architecture requires that the NodeStateManager (NSM) is independent +* from the D-Bus binding and generated code. The interface functions of the +* library have to be implemented according to their description. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* 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 +* +**********************************************************************************************************************/ + + +/********************************************************************************************************************** +* +* HEADER FILE INCLUDES +* +**********************************************************************************************************************/ + +#include "NodeStateTypes.h" /* NodeStateTypes to communicate with NSM */ +#include "gio/gio.h" /* glib types for easier ICP connection */ + +/********************************************************************************************************************** +* +* TYPE +* +**********************************************************************************************************************/ + +/* Type definitions of callbacks that the NSM registers for the object interfaces */ + +typedef NsmErrorStatus_e (*NSMA_tpfSetBootModeCb) (const gint i32BootMode); +typedef NsmErrorStatus_e (*NSMA_tpfSetNodeStateCb) (const NsmNodeState_e enNodeState); +typedef NsmErrorStatus_e (*NSMA_tpfSetAppModeCb) (const NsmApplicationMode_e enApplMode); +typedef NsmErrorStatus_e (*NSMA_tpfRequestNodeRestartCb) (const NsmRestartReason_e enRestartReason, + const guint u32RestartType); +typedef NsmErrorStatus_e (*NSMA_tpfSetAppHealthStatusCb) (const gchar *sAppName, + const gboolean boAppState); +typedef gboolean (*NSMA_tpfCheckLucRequiredCb) (void); +typedef NsmErrorStatus_e (*NSMA_tpfRegisterSessionCb) (const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId, + const NsmSessionState_e ensessionState); +typedef NsmErrorStatus_e (*NSMA_tpfUnRegisterSessionCb) (const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId); +typedef NsmErrorStatus_e (*NSMA_tpfRegisterLifecycleClientCb) (const gchar *sBusName, + const gchar *sObjName, + const guint u32ShutdownMode, + const guint u32TimeoutMs); +typedef NsmErrorStatus_e (*NSMA_tpfUnRegisterLifecycleClientCb)(const gchar *sBusName, + const gchar *sObjName, + const guint u32ShutdownMode); +typedef NsmErrorStatus_e (*NSMA_tpfGetAppModeCb) (NsmApplicationMode_e *penAppMode); +typedef NsmErrorStatus_e (*NSMA_tpfGetSessionStateCb) (const gchar *sSessionName, + const NsmSeat_e enSeatId, + NsmSessionState_e *penSessionState); +typedef NsmErrorStatus_e (*NSMA_tpfGetNodeStateCb) (NsmNodeState_e *penNodeState); +typedef NsmErrorStatus_e (*NSMA_tpfSetSessionStateCb) (const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId, + const NsmSessionState_e enSessionState); +typedef guint (*NSMA_tpfGetAppHealthCountCb) (void); +typedef guint (*NSMA_tpfGetInterfaceVersionCb) (void); + + +/* Type definition for the management of Lifecycle clients */ +typedef gpointer NSMA_tLcConsumerHandle; +typedef void (*NSMA_tpfLifecycleReqFinish)(const NsmErrorStatus_e enErrorStatus); + +/* Type definition to wrap all callbacks in a structure */ +typedef struct +{ + NSMA_tpfSetBootModeCb pfSetBootModeCb; + NSMA_tpfSetNodeStateCb pfSetNodeStateCb; + NSMA_tpfSetAppModeCb pfSetAppModeCb; + NSMA_tpfRequestNodeRestartCb pfRequestNodeRestartCb; + NSMA_tpfSetAppHealthStatusCb pfSetAppHealthStatusCb; + NSMA_tpfCheckLucRequiredCb pfCheckLucRequiredCb; + NSMA_tpfRegisterSessionCb pfRegisterSessionCb; + NSMA_tpfUnRegisterSessionCb pfUnRegisterSessionCb; + NSMA_tpfRegisterLifecycleClientCb pfRegisterLifecycleClientCb; + NSMA_tpfUnRegisterLifecycleClientCb pfUnRegisterLifecycleClientCb; + NSMA_tpfGetAppModeCb pfGetAppModeCb; + NSMA_tpfGetSessionStateCb pfGetSessionStateCb; + NSMA_tpfGetNodeStateCb pfGetNodeStateCb; + NSMA_tpfSetSessionStateCb pfSetSessionStateCb; + NSMA_tpfGetAppHealthCountCb pfGetAppHealthCountCb; + NSMA_tpfGetInterfaceVersionCb pfGetInterfaceVersionCb; + NSMA_tpfLifecycleReqFinish pfLcClientRequestFinish; +} NSMA_tstObjectCallbacks; + + +/********************************************************************************************************************** +* +* GLOBAL VARIABLES +* +**********************************************************************************************************************/ + +/* There are no exported global variables */ + + +/********************************************************************************************************************** +* +* FUNCTION PROTOTYPE +* +**********************************************************************************************************************/ + +/********************************************************************************************************************** +* +* The function is called to initialize the NodeStateAccess library. +* It initializes the internal variables and creates a new GMainLoop. +* +* @return TRUE: The NodeStateAccess library could be initialized. +* FALSE: Error initializing the NodeStateAccess library. +* +**********************************************************************************************************************/ +gboolean NSMA_boInit(const NSMA_tstObjectCallbacks *pstCallbacks); + + +/********************************************************************************************************************** +* +* The function is used to send the "NodeState" signal via the IPC. +* +* @param enNodeState: NodeState to be send. +* +* @return TRUE: Signal has been send successfully. +* FALSE: Error. Signal could not be send. +* +**********************************************************************************************************************/ +gboolean NSMA_boSendNodeStateSignal(const NsmNodeState_e enNodeState); + + +/********************************************************************************************************************** +* +* The function is used to send the "SessionChanged" signal via the IPC. +* +* @param pstSession: Pointer to session structure that should be send. +* +* @return TRUE: Signal has been send successfully. +* FALSE: Error. Signal could not be send. +* +**********************************************************************************************************************/ +gboolean NSMA_boSendSessionSignal(const NsmSession_s *pstSession); + + +/********************************************************************************************************************** +* +* The function is used to send the "ApplicationMode" signal via the IPC. +* +* @param enApplicationMode: ApplicationMode to be send. +* +* @return TRUE: Signal has been send successfully. +* FALSE: Error. Signal could not be send. +* +**********************************************************************************************************************/ +gboolean NSMA_boSendApplicationModeSignal(const NsmApplicationMode_e enApplicationMode); + + +/********************************************************************************************************************** +* +* The function is used to set the value of the BootMode property. +* +* @param i32BootMode: New value of BootMode property. +* +* @return TRUE: Successfully set the properties value. +* FALSE: Error setting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boSetBootMode(gint i32BootMode); + + +/********************************************************************************************************************** +* +* The function is used to get the value of the BootMode property. +* +* @param pi32BootMode: Pointer where to store the BootMode. +* +* @return TRUE: Successfully got the properties value. +* FALSE: Error getting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boGetBootMode(gint *pi32BootMode); + + +/********************************************************************************************************************** +* +* The function is used to set the value of the RestartReason property. +* +* @param enRestartReason: New value of RestartReason property. +* +* @return TRUE: Successfully set the properties value. +* FALSE: Error setting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boSetRestartReason(const NsmRestartReason_e enRestartReason); + + +/********************************************************************************************************************** +* +* The function is used to get the value of the RestartReason property. +* +* @param penRestartReason: Pointer where to store the RestartReason. +* +* @return TRUE: Successfully got the properties value. +* FALSE: Error getting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boGetRestartReason(NsmRestartReason_e *penRestartReason); + + +/********************************************************************************************************************** +* +* The function is used to set the value of the WakeUpReason property. +* +* @param enRunningReason: New value of WakeUpReason property. +* +* @return TRUE: Successfully set the properties value. +* FALSE: Error setting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boSetRunningReason(const NsmRunningReason_e enRunningReason); + + +/********************************************************************************************************************** +* +* The function is used to get the value of the RunningReason property. +* +* @param penRunningReason: Pointer where to store the RunningReason. +* +* @return TRUE: Successfully got the properties value. +* FALSE: Error getting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boGetRunningReason(NsmRunningReason_e *penRunningReason); + + +/********************************************************************************************************************** +* +* The function is used to set the value of the ShutdownReason property. +* +* @param enShutdownReason: New value of ShutdownReason property. +* +* @return TRUE: Successfully set the properties value. +* FALSE: Error setting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boSetShutdownReason(const NsmShutdownReason_e enShutdownReason); + + +/********************************************************************************************************************** +* +* The function is used to get the value of the ShutdownReason property. +* +* @param penShutdownReason: Pointer where to store the ShutdownReason. +* +* @return TRUE: Successfully got the properties value. +* FALSE: Error getting the properties value. +* +**********************************************************************************************************************/ +gboolean NSMA_boGetShutdownReason(NsmShutdownReason_e *penShutdownReason); + + +/********************************************************************************************************************** +* +* The function is used to create a LifecycleConsumer client. +* +* @param sBusName: Bus name of the client object. +* @param sObjName: Object name of the client object. +* @param u32TimeoutMs: Timeout for client calls in ms. +* +* @return Handle to the new life cycle consumer or NULL, if there was an error. +* +**********************************************************************************************************************/ +NSMA_tLcConsumerHandle NSMA_hCreateLcConsumer(const gchar* sBusName, const gchar* sObjName, const guint u32TimeoutMs); + + +/********************************************************************************************************************** +* +* The function is used to call the "LifecycleRequest" method of a client. +* +* @param hLcClient: Handle of the client (created with "NSMA_hCreateLcConsumer"). +* @param u32ShutdownType: Shutdown type. +* +* @return TRUE: Successfully called client +* FALSE: Error calling the client. +* +**********************************************************************************************************************/ +gboolean NSMA_boCallLcClientRequest(NSMA_tLcConsumerHandle hLcClient, guint u32ShutdownType); + + +/********************************************************************************************************************** +* +* The function is called to set the default timeout for calls to the life cycle client. +* +* @param hLcClient: Handle of the life cycle client. +* @param u32TimeoutMs: Timeout value in ms. +* +* @return TRUE: Successfully set timeout time for client. +* FALSE: Error setting the clients timeout time. +* +**********************************************************************************************************************/ +gboolean NSMA_boSetLcClientTimeout(NSMA_tLcConsumerHandle hClient, guint u32TimeoutMs); + + +/********************************************************************************************************************** +* +* The function is called to get the default timeout for calls to the life cycle client. +* +* @param hLcClient: Handle of the life cycle client. +* @param pu32TimeoutMs: Pointer where to store the timeout value in ms. +* +* @return TRUE: Successfully got timeout time for client. +* FALSE: Error getting the clients timeout time. +* +**********************************************************************************************************************/ +gboolean NSMA_boGetLcClientTimeout(NSMA_tLcConsumerHandle hClient, guint *pu32TimeoutMs); + + +/********************************************************************************************************************** +* +* The function is used to delete a "LifecycleRequest". +* +* @param hLcClient: Handle of the client (created with "NSMA_hCreateLcConsumer"). +* +* @return TRUE: Successfully freed clients memory. +* FALSE: Error freeing the clients memory. +* +**********************************************************************************************************************/ +gboolean NSMA_boFreeLcConsumerProxy(NSMA_tLcConsumerHandle hLcConsumer); + + +/********************************************************************************************************************** +* +* The function is blocking. It waits in a loop for events and forwards them to the related callback functions. +* +* @return TRUE: Returned because of user call. +* FALSE: Returned because of an internal error. +* +**********************************************************************************************************************/ +gboolean NSMA_boWaitForEvents(void); + + +/********************************************************************************************************************** +* +* The function is used to force the return of "NSMA_boWaitForEvents". +* +* @return TRUE: Accepted return request. +* FALSE: Error. Return request not accepted. +* +**********************************************************************************************************************/ +gboolean NSMA_boQuitEventLoop(void); + + +/********************************************************************************************************************** +* +* The function is de-initialize the NodeStateAccess library and release all memory used by it. +* +* @return TRUE: Successfully de-initialized access library. +* FALSE: Error de-initializing the library. +* +**********************************************************************************************************************/ +gboolean NSMA_boDeInit(void); + + +#endif /* NODESTATEACCESS_H_ */ diff --git a/NodeStateAccessStub/model/org.genivi.NodeStateManager.Consumer.xml b/NodeStateAccessStub/model/org.genivi.NodeStateManager.Consumer.xml new file mode 100644 index 0000000..e5845d3 --- /dev/null +++ b/NodeStateAccessStub/model/org.genivi.NodeStateManager.Consumer.xml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleConsumer.xml b/NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleConsumer.xml new file mode 100644 index 0000000..ec1162b --- /dev/null +++ b/NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleConsumer.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + diff --git a/NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleControl.xml b/NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleControl.xml new file mode 100644 index 0000000..c8b45da --- /dev/null +++ b/NodeStateAccessStub/model/org.genivi.NodeStateManager.LifecycleControl.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NodeStateMachineStub/Makefile.am b/NodeStateMachineStub/Makefile.am new file mode 100644 index 0000000..e07ce57 --- /dev/null +++ b/NodeStateMachineStub/Makefile.am @@ -0,0 +1,23 @@ +####################################################################################################################### +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Jean-Pierre.Bogler@continental-corporation.com +# +# Makefile template for the NodeStateMachineStub +# +# Process this file with automake to produce a Makefile.in. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# 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/. +# +####################################################################################################################### + +noinst_LTLIBRARIES = libNodeStateMachine.la + +libNodeStateMachine_la_CFLAGS = \ + -I$(top_srcdir)/NodeStateManager \ + $(PLATFORM_CFLAGS) + +libNodeStateMachine_la_SOURCES = NodeStateMachine.c NodeStateMachine.h diff --git a/NodeStateMachineStub/NodeStateMachine.c b/NodeStateMachineStub/NodeStateMachine.c new file mode 100644 index 0000000..07f22c1 --- /dev/null +++ b/NodeStateMachineStub/NodeStateMachine.c @@ -0,0 +1,114 @@ +/********************************************************************************************************************** +* +* Copyright (C) 2012 Continental Automotive Systems, Inc. +* +* Author: Jean-Pierre.Bogler@continental-corporation.com +* +* Header for the NodestateMachine stub. +* +* The header file defines the interfaces offered by the NodeStateMachine stub. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* 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. +* +**********************************************************************************************************************/ + + +/********************************************************************************************************************** +* +* Header includes +* +**********************************************************************************************************************/ + +#include "NodeStateMachine.h" /* own header file */ +#include "NodeStateManager.h" +#include "NodeStateTypes.h" +#include + + +/********************************************************************************************************************** +* +* Local defines, macros, constants and type definitions. +* +**********************************************************************************************************************/ + +/* There are currently no local defines, macros or types */ + + +/********************************************************************************************************************** +* +* Local variables +* +**********************************************************************************************************************/ + +/* There are currently no local variables */ + +/********************************************************************************************************************** +* +* Prototypes for file local functions (see implementation for description) +* +**********************************************************************************************************************/ + +/* There are no file local functions */ + +/********************************************************************************************************************** +* +* Local (static) functions +* +**********************************************************************************************************************/ + +/* There are no file local functions */ + +/********************************************************************************************************************** +* +* Interfaces, exported functions. See header for detailed description. +* +**********************************************************************************************************************/ + +unsigned char NsmcInit(void) +{ + printf("NSMC: NsmcInit called.\n"); + + return 1; +} + + +unsigned char NsmcLucRequired(void) +{ + printf("NSMC: NsmcLucRequired called.\n"); + + return 1; +} + + +NsmErrorStatus_e NsmcSetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen) +{ + printf("NSMC: NsmcSetData called. enData: %d. pData: 0x%08X. u32DataLen: %d\n", enData, (unsigned int) pData, u32DataLen); + + return NsmErrorStatus_Ok; +} + + +unsigned char NsmcRequestNodeRestart(void) +{ + printf("NSMC: NsmcRequestNodeRestart called.\n"); + + return 1; +} + + +unsigned int NsmcGetInterfaceVersion(void) +{ + printf("NSMC: NsmcGetInterfaceVersion called.\n"); + + return NSMC_INTERFACE_VERSION; +} + + + + diff --git a/NodeStateMachineStub/NodeStateMachine.h b/NodeStateMachineStub/NodeStateMachine.h new file mode 100644 index 0000000..c486d20 --- /dev/null +++ b/NodeStateMachineStub/NodeStateMachine.h @@ -0,0 +1,135 @@ +#ifndef NSM_NODESTATEMACHINE_H +#define NSM_NODESTATEMACHINE_H + + +/********************************************************************************************************************** +* +* Copyright (C) 2012 Continental Automotive Systems, Inc. +* +* Author: Jean-Pierre.Bogler@continental-corporation.com +* +* Header for the NodestateMachine stub. +* +* The header file defines the interfaces offred by the NodeStateMachine stub. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* 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 +extern "C" +{ +#endif + +/********************************************************************************************************************** +* +* HEADER FILE INCLUDES +* +**********************************************************************************************************************/ + +#include "NodeStateTypes.h" + +/********************************************************************************************************************** +* +* CONSTANTS +* +**********************************************************************************************************************/ + +/** + * Module version, use SswVersion to interpret the value. + * The lower significant byte is equal 0 for released version only + */ + +#define NSMC_INTERFACE_VERSION 0x01010000U + + +/********************************************************************************************************************** +* +* TYPE +* +**********************************************************************************************************************/ + +/* There are no own types defined */ + + +/********************************************************************************************************************** +* +* GLOBAL VARIABLES +* +**********************************************************************************************************************/ + +/* There are no exported global variables */ + + +/********************************************************************************************************************** +* +* FUNCTION PROTOTYPE +* +**********************************************************************************************************************/ + +/** \brief Initialize the NodeStateMachine +\retval true: The NodeStateMachine could be initialized and is running. false: An error occurred. NodeStateMachine not started. + +This function will be used to initialize the Node State Machine, it will be called by the Node State Manager. +At the point where this function returns the machine is available to accept events via its interfaces from +the NSM. It is envisaged that in this call the NSMC will create and transfer control of the NSMC to its own +thread and will return in the original thread.*/ +unsigned char NsmcInit(void); + + +/** \brief Check for Last User Context +\retval true: Last User Context (LUC) is required. false: No LUC required. + +This will be used by the NSM to check whether in the current Lifecycle the Last User Context (LUC) should +be started. This allows the product to define its own handling for specific Application modes. */ +unsigned char NsmcLucRequired(void); + + +/** \brief Set data in the NodeStateMachine. +\param[in] enData Type of the data to set (see ::NsmDataType_e). +\param[in] pData Pointer to the memory location containing the data. +\param[in] u32DataLen Length of the data that should be set (in byte). +\retval see ::NsmErrorStatus_e + +This is a generic interface that can be used by the NSM to inform the NSMC about changes +to data items (i.e. events that have occurred in the system) */ +NsmErrorStatus_e NsmcSetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen); + + +/** \brief Request a NodeRestart. +\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); + + +/** \brief Get version of the interface +\retval Version of the interface as defined in ::SswVersion_t + +This function asks the lifecycle to perform a restart of the main controller. */ +unsigned int NsmcGetInterfaceVersion(void); + + +/********************************************************************************************************************** +* +* MACROS +* +**********************************************************************************************************************/ + +/* There are no macros defined */ + + +#ifdef __cplusplus +} +#endif +/** \} */ /* End of SSW_NSMC_INTERFACE */ +/** \} */ /* End of SSW_NSMC_TEMPLATE */ +#endif /* NSM_NODESTATEMACHINE_H */ diff --git a/NodeStateManager/Makefile.am b/NodeStateManager/Makefile.am new file mode 100644 index 0000000..6de96e5 --- /dev/null +++ b/NodeStateManager/Makefile.am @@ -0,0 +1,55 @@ +####################################################################################################################### +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Jean-Pierre.Bogler@continental-corporation.com +# +# Makefile template for the NodeStateManager +# +# Process this file with automake to produce a Makefile.in. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# 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/. +# +####################################################################################################################### + +bin_PROGRAMS = NodeStateManager + +NodeStateManager_SOURCES = NodeStateManager.c + +NodeStateManager_CFLAGS = \ + -I$(top_srcdir)/NodeStateMachineStub \ + -I$(top_srcdir)/NodeStateAccessStub \ + $(DLT_CFLAGS) \ + $(GIO_CFLAGS) \ + $(GIO_UNIX_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GOBJECT_CFLAGS) \ + $(PLATFORM_CFLAGS) + +NodeStateManager_LDFLAGS = \ + $(PLATFORM_LDFLAGS) + +NodeStateManager_LDADD = \ + -L$(top_srcdir)/NodeStateAccessStub -lNodeStateAccess \ + -L$(top_srcdir)/NodeStateMachineStub -lNodeStateMachine \ + $(DLT_LIBS) \ + $(GIO_LIBS) \ + $(GIO_UNIX_LIBS) \ + $(GLIB_LIBS) \ + $(GOBJECT_LIBS) + +include_HEADERS = NodeStateManager.h NodeStateTypes.h + +systemdsystemunit_DATA = config/nodestatemanager-daemon.service + + +dbussystemunit_DATA = config/org.genivi.NodeStateManager.LifeCycleControl.service + + +dbuspolicy_DATA = config/org.genivi.NodeStateManager.conf + +EXTRA_DIST = $(systemdsystemunit_DATA) \ + $(dbussystemunit_DATA) \ + $(dbuspolicy_DATA) diff --git a/NodeStateManager/NodeStateManager.c b/NodeStateManager/NodeStateManager.c new file mode 100644 index 0000000..c92188f --- /dev/null +++ b/NodeStateManager/NodeStateManager.c @@ -0,0 +1,2494 @@ +/********************************************************************************************************************** +* +* Copyright (C) 2012 Continental Automotive Systems, Inc. +* +* Author: Jean-Pierre.Bogler@continental-corporation.com +* +* Implementation of the NodeStateManager +* +* The NodeStateManager (NSM) is a central state manager for the system node. It manages the "NodeState", +* the "ApplicationMode" and many other states of the complete system. In addition, the NSM offers a +* session handling and a shutdown management. +* The NSM communicates with the NodeStateMachine (NSMC) to request and inform it about state changes +* and the NodeStateAccess (NSMA) to connect to the D-Bus. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* 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 +* +**********************************************************************************************************************/ + + +/********************************************************************************************************************** +* +* 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 */ + +/********************************************************************************************************************** +* +* Local defines, macros and type definitions. +* +**********************************************************************************************************************/ + +/* The type defines the structure for a lifecycle consumer client */ +typedef struct +{ + gchar *sBusName; /* Bus name of the lifecycle client */ + gchar *sObjName; /* Object path of the client */ + guint32 u32RegisteredMode; /* Bit array of shutdown modes */ + NSMA_tLcConsumerHandle hClient; /* Handle for proxy object for lifecycle client */ + gboolean boShutdown; /* Only "run up" clients which are shut down */ +} NSM__tstLifecycleClient; + + +/* The type is used to store failed applications. A struct is used to allow extsions in future */ +typedef struct +{ + gchar sName[NSM_MAX_SESSION_OWNER_LENGTH]; +} NSM__tstFailedApplication; + + +/* List of names for the available default sessions, will are automatically provided by NSM */ +static const gchar* NSM__asDefaultSessions[] = { "DiagnosisSession", + "HevacSession", + "HmiActiveSession", + "NetworkActiveSession", + "NetworkPassiveSession", + "PdcSession", + "PermanentModeSession", + "PhoneSession", + "RvcSession", + "SwlSession", + "ProductLcSession", + "PlatformThermalSession", + "PlatformSupplySession", + "PersistencySession" + }; + +/********************************************************************************************************************** +* +* Prototypes for file local functions (see implementation for description) +* +**********************************************************************************************************************/ + +/* Helper functions to destruct objects */ +static void NSM__vFreeFailedApplicationObject(gpointer pFailedApplication); +static void NSM__vFreeSessionObject (gpointer pSession ); +static void NSM__vFreeLifecycleClientObject (gpointer pLifecycleClient ); + + +/* Helper functions to compare objects in lists */ +static gboolean NSM__boIsPlatformSession (NsmSession_s *pstSession); +static gint NSM__i32LifecycleClientCompare (gconstpointer pL1, gconstpointer pL2); +static gint NSM__i32SessionOwnerNameSeatCompare(gconstpointer pS1, gconstpointer pS2); +static gint NSM__i32SessionNameSeatCompare (gconstpointer pS1, gconstpointer pS2); +static gint NSM__i32SessionOwnerCompare (gconstpointer pS1, gconstpointer pS2); +static gint NSM__i32ApplicationCompare (gconstpointer pA1, gconstpointer pA2); + + +/* Helper functions to recognize failed applications and disable their sessions */ +static void NSM__vDisableSessionsForApp(NSM__tstFailedApplication* pstFailedApp); +static NsmErrorStatus_e NSM__enSetAppStateFailed (NSM__tstFailedApplication* pstFailedApp); +static NsmErrorStatus_e NSM__enSetAppStateValid (NSM__tstFailedApplication* pstFailedApp); + + +/* Helper functions to control and start the "lifecycle request" sequence */ +static void NSM__vCallNextLifecycleClient(void); +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__enSetNodeState (NsmNodeState_e enNodeState, + gboolean boInformBus, + gboolean boInformMachine); +static NsmErrorStatus_e NSM__enSetBootMode (const gint i32BootMode, + gboolean boInformMachine); +static NsmErrorStatus_e NSM__enSetApplicationMode (NsmApplicationMode_e enApplicationMode, + gboolean boInformBus, + gboolean boInformMachine); +static NsmErrorStatus_e NSM__enSetShutdownReason (NsmShutdownReason_e enNewShutdownReason, + gboolean boInformMachine); + +static void NSM__vPublishSessionChange (NsmSession_s *pstChangedSession, + gboolean boInformBus, + gboolean boInformMachine); +static NsmErrorStatus_e NSM__enSetDefaultSessionState(NsmSession_s *pstSession, + gboolean boInformBus, + gboolean boInformMachine); +static NsmErrorStatus_e NSM__enSetProductSessionState(NsmSession_s *pstSession, + gboolean boInformBus, + gboolean boInformMachine); +static NsmErrorStatus_e NSM__enSetSessionState (NsmSession_s *pstSession, + gboolean boInformBus, + gboolean boInformMachine); +static NsmErrorStatus_e NSM__enGetSessionState (NsmSession_s *pstSession); + + +/* Internal functions that are directly used from D-Bus and StateMachine */ +static NsmErrorStatus_e NSM__enGetNodeState (NsmNodeState_e *penNodeState); +static NsmErrorStatus_e NSM__enGetApplicationMode(NsmApplicationMode_e *penApplicationMode); + + +/* Callbacks for D-Bus interfaces of the NodeStateManager */ +static NsmErrorStatus_e NSM__enOnHandleSetBootMode (const gint i32BootMode); +static NsmErrorStatus_e NSM__enOnHandleSetNodeState (const NsmNodeState_e enNodeState); +static NsmErrorStatus_e NSM__enOnHandleSetApplicationMode (const NsmApplicationMode_e enApplMode); +static NsmErrorStatus_e NSM__enOnHandleRequestNodeRestart (const NsmRestartReason_e enRestartReason, + const guint u32RestartType); +static NsmErrorStatus_e NSM__enOnHandleSetAppHealthStatus (const gchar *sAppName, + const gboolean boAppState); +static gboolean NSM__boOnHandleCheckLucRequired (void); +static NsmErrorStatus_e NSM__enOnHandleRegisterSession (const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId, + const NsmSessionState_e enSessionState); +static NsmErrorStatus_e NSM__enOnHandleUnRegisterSession (const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId); +static NsmErrorStatus_e NSM__enOnHandleRegisterLifecycleClient (const gchar *sBusName, + const gchar *sObjName, + const guint u32ShutdownMode, + const guint u32TimeoutMs); +static NsmErrorStatus_e NSM__enOnHandleUnRegisterLifecycleClient(const gchar *sBusName, + const gchar *sObjName, + const guint u32ShutdownMode); +static NsmErrorStatus_e NSM__enOnHandleGetSessionState (const gchar *sSessionName, + const NsmSeat_e enSeatId, + NsmSessionState_e *penSessionState); +static NsmErrorStatus_e NSM__enOnHandleSetSessionState (const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId, + const NsmSessionState_e enSessionState); +static guint NSM__u32OnHandleGetAppHealthCount (void); +static guint NSM__u32OnHandleGetInterfaceVersion (void); + +/* Functions to simplify internal work flow */ +static void NSM__vInitializeVariables (void); +static void NSM__vCreatePlatformSessions(void); +static void NSM__vCreateMutexes (void); +static void NSM__vDeleteMutexes (void); + +/* LTPROF helper function */ +static void NSM__vLtProf(gchar *pszBus, gchar *pszObj, guint32 dwReason, gchar *pszInOut, guint32 dwValue); +static void NSM__vSyslogOpen(void); +static void NSM__vSyslogClose(void); + + +/********************************************************************************************************************** +* +* Local variables and constants +* +**********************************************************************************************************************/ + +/* Context for Log'n'Trace */ +DLT_DECLARE_CONTEXT(NsmContext); + +/* Variables for "Properties" hosted by the NSM */ +static GMutex *NSM__pSessionMutex = NULL; +static GSList *NSM__pSessions = NULL; + +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 GSList *NSM__pFailedApplications = NULL; + +/* Variables for internal state management (of lifecycle requests) */ +static NSM__tstLifecycleClient *NSM__pCurrentLifecycleClient = NULL; + +/* Constant array of callbacks which are registered at the NodeStateAccess library */ +static const NSMA_tstObjectCallbacks NSM__stObjectCallBacks = { &NSM__enOnHandleSetBootMode, + &NSM__enOnHandleSetNodeState, + &NSM__enOnHandleSetApplicationMode, + &NSM__enOnHandleRequestNodeRestart, + &NSM__enOnHandleSetAppHealthStatus, + &NSM__boOnHandleCheckLucRequired, + &NSM__enOnHandleRegisterSession, + &NSM__enOnHandleUnRegisterSession, + &NSM__enOnHandleRegisterLifecycleClient, + &NSM__enOnHandleUnRegisterLifecycleClient, + &NSM__enGetApplicationMode, + &NSM__enOnHandleGetSessionState, + &NSM__enGetNodeState, + &NSM__enOnHandleSetSessionState, + &NSM__u32OnHandleGetAppHealthCount, + &NSM__u32OnHandleGetInterfaceVersion, + &NSM__vOnLifecycleRequestFinish + }; + +/********************************************************************************************************************** +* +* Local (static) functions +* +**********************************************************************************************************************/ + + +/********************************************************************************************************************** +* +* This helper function is called from various places to check if a session is a "platform" session. +* +* @param pstSession: Pointer to the session for which a check should be done, if it is a platform session +* +* @return TRUE: The session is a "platform" session +* FALSE: The session is not a "platform" session +* +**********************************************************************************************************************/ +static gboolean NSM__boIsPlatformSession(NsmSession_s *pstSession) +{ + /* Function local variables */ + gboolean boIsPlatformSession = FALSE; + guint16 u16SessionIdx = 0; + + for(u16SessionIdx = 0; + (u16SessionIdx < sizeof(NSM__asDefaultSessions)/sizeof(gchar*)) + && (boIsPlatformSession == FALSE); + u16SessionIdx++) + { + boIsPlatformSession = (g_strcmp0(pstSession->sName, NSM__asDefaultSessions[u16SessionIdx]) == 0); + } + + return boIsPlatformSession; +} + + +/********************************************************************************************************************** +* +* The function is called from IPC and StateMachine to set the NodeState. +* +* @param enNodeState: New NodeState that should be stored. +* @param boInformBus: Defines whether a D-Bus signal should be send when the NodeState could be changed. +* @param boInformMachine: Defines whether the StateMachine should be informed about the new NodeState. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetNodeState(NsmNodeState_e enNodeState, gboolean boInformBus, gboolean boInformMachine) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + + /* Check if the passed parameter is valid */ + if((enNodeState > NsmNodeState_NotSet) && (enNodeState < NsmNodeState_Last)) + { + /* Assert that the Node not already is shut down. Otherwise it will switch of immediately */ + enRetVal = NsmErrorStatus_Ok; + + g_mutex_lock(NSM__pNodeStateMutex); + + /* Only store the new value and emit a signal, if the new value is different */ + if(NSM__enNodeState != enNodeState) + { + /* Store the last NodeState, before switching to the new one */ + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed NodeState." ), + DLT_STRING(" Old NodeState: "), DLT_INT((gint) NSM__enNodeState), + DLT_STRING(" New NodeState: "), DLT_INT((gint) enNodeState )); + + + /* Store the passed NodeState and emit a signal to inform system that the NodeState changed */ + NSM__enNodeState = enNodeState; + + /* If required, inform the D-Bus about the change (send signal) */ + if(boInformBus == TRUE) + { + (void) NSMA_boSendNodeStateSignal(NSM__enNodeState); + } + + /* If required, inform the StateMachine about the change */ + if(boInformMachine == TRUE) + { + NsmcSetData(NsmDataType_NodeState, (unsigned char*) &NSM__enNodeState, sizeof(NsmDataType_NodeState)); + } + + /* Leave the lock now, because its not recursive. 'NSM__vCallNextLifecycleClient' may need it. */ + g_mutex_unlock(NSM__pNodeStateMutex); + + /* Check if a new life cycle request needs to be started based on the new ShutdownType */ + if(NSM__pCurrentLifecycleClient == NULL) + { + NSM__vCallNextLifecycleClient(); + } + } + else + { + /* NodeState stays the same. Just leave the lock. */ + g_mutex_unlock(NSM__pNodeStateMutex); + } + } + else + { + /* Error: The passed boot mode is invalid. Return an error. */ + enRetVal = NsmErrorStatus_Parameter; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to change NodeState. Invalid parameter."), + DLT_STRING(" Old NodeState: "), DLT_INT(NSM__enNodeState ), + DLT_STRING(" Desired NodeState: "), DLT_INT((gint) enNodeState) ); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called from IPC and StateMachine to get the NodeState. +* +* @return see NsmNodeState_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enGetNodeState(NsmNodeState_e *penNodeState) +{ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + if(penNodeState != NULL) + { + enRetVal = NsmErrorStatus_Ok; + + g_mutex_lock(NSM__pNodeStateMutex); + *penNodeState = NSM__enNodeState; + g_mutex_unlock(NSM__pNodeStateMutex); + } + else + { + enRetVal = NsmErrorStatus_Parameter; + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called from IPC and StateMachine to set the BootMode. +* +* @param i32BootMode: New BootMode that should be stored. +* @param boInformBus: Defines whether a D-Bus signal should be send when the BootMode could be changed. +* @param boInformMachine: Defines whether the StateMachine should be informed about the new BootMode. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetBootMode(const gint i32BootMode, gboolean boInformMachine) +{ + /* Function local variables */ + gint i32CurrentBootMode = 0; + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + /* The BootMode property should be thread safe by D-Bus. No critical section need. */ + (void) NSMA_boGetBootMode(&i32CurrentBootMode); + enRetVal = NsmErrorStatus_Ok; + + if(i32CurrentBootMode != i32BootMode) + { + (void) NSMA_boSetBootMode(i32BootMode); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed BootMode." ), + DLT_STRING(" Old BootMode: "), DLT_INT(i32CurrentBootMode), + DLT_STRING(" New BootMode: "), DLT_INT(i32BootMode )); + + /* Inform the machine if desired. The D-Bus will auto. update, because this is property */ + if(boInformMachine == TRUE) + { + NsmcSetData(NsmDataType_BootMode, (unsigned char*) &i32BootMode, sizeof(gint)); + } + } + + /* Return ok. There is no limitation for this value. */ + return enRetVal; +} + +/********************************************************************************************************************** +* +* The function is called from IPC and StateMachine to set the ApplicationMode. +* +* @param enApplicationMode: New application mode that should be stored. +* @param boInformBus: Defines whether a D-Bus signal should be send when the ApplicationMode could be changed. +* @param boInformMachine: Defines whether the StateMachine should be informed about the new ApplicationMode. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetApplicationMode(NsmApplicationMode_e enApplicationMode, gboolean boInformBus, gboolean boInformMachine) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + + /* Check if the passed parameter is valid */ + if((enApplicationMode > NsmApplicationMode_NotSet) && (enApplicationMode < NsmApplicationMode_Last)) + { + /* The passed parameter is valid. Return OK */ + enRetVal = NsmErrorStatus_Ok; + + g_mutex_lock(NSM__pApplicationModeMutex); + + /* Only store the new value and emit a signal, if the new value is different */ + if(NSM__enApplicationMode != 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)); + + NSM__enApplicationMode = enApplicationMode; + + if(boInformBus == TRUE) + { + NSMA_boSendApplicationModeSignal(NSM__enApplicationMode); + } + + if(boInformMachine == TRUE) + { + NsmcSetData(NsmDataType_AppMode, (unsigned char*) &NSM__enApplicationMode, sizeof(NsmApplicationMode_e)); + } + } + + g_mutex_unlock(NSM__pApplicationModeMutex); + } + 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)); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called from IPC and StateMachine to get the ApplicationMode. +* +* @return see NsmApplicationMode_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enGetApplicationMode(NsmApplicationMode_e *penApplicationMode) +{ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + if(penApplicationMode != NULL) + { + enRetVal = NsmErrorStatus_Ok; + g_mutex_lock(NSM__pApplicationModeMutex); + *penApplicationMode = NSM__enApplicationMode; + g_mutex_unlock(NSM__pApplicationModeMutex); + } + else + { + enRetVal = NsmErrorStatus_Parameter; + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called from the StateMachine. There is no D-Bus interface to set the ShutdownReason, +* because it is a property. +* +* @param enNewShutdownReason: New ShutdownReason that should be stored. +* @param boInformMachine: Determines if StateMachine needs to be called on a successful change. +* Most of the time this should be false, because the machine sets the +* value and can check the return value for errors. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetShutdownReason(NsmShutdownReason_e enNewShutdownReason, gboolean boInformMachine) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + NsmShutdownReason_e enCurrentShutdownReason = NsmShutdownReason_NotSet; + + /* Check if the passed parameter is valid */ + if((enNewShutdownReason > NsmShutdownReason_NotSet) && (enNewShutdownReason < NsmShutdownReason_Last)) + { + /* The passed parameter is valid. Return OK */ + enRetVal = NsmErrorStatus_Ok; + (void) NSMA_boGetShutdownReason(&enCurrentShutdownReason); + + /* Only store the new value and emit a signal, if the new value is different */ + if(enNewShutdownReason != enCurrentShutdownReason) + { + /* Store new value and emit signal with new application mode */ + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed ShutdownReason."), + DLT_STRING(" Old ShutdownReason: "), DLT_INT((gint) enCurrentShutdownReason), + DLT_STRING(" New ShutdownReason: "), DLT_INT((gint) enNewShutdownReason )); + + (void) NSMA_boSetShutdownReason(enNewShutdownReason); + + if(boInformMachine == TRUE) + { + NsmcSetData(NsmDataType_ShutdownReason, (unsigned char*) &enNewShutdownReason, sizeof(NsmShutdownReason_e)); + } + } + } + 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 ShutdownReason. Invalid parameter." ), + DLT_STRING(" Old ShutdownReason: "), DLT_INT((gint) enCurrentShutdownReason), + DLT_STRING(" Desired ShutdownReason: "), DLT_INT((gint) enNewShutdownReason )); + } + + return enRetVal; +} + +/********************************************************************************************************************** +* +* The function is called when a session state changed. It informs the system (IPC and StateMachine) about +* the changed session state. +* +* @param pstSession: Pointer to structure with updated session information. +* @param boInformBus: Defines whether a D-Bus signal should be send on session change. +* @param boInformMachine: Defines whether the StateMachine should be informed about session change. +* +**********************************************************************************************************************/ +static void NSM__vPublishSessionChange(NsmSession_s *pstChangedSession, gboolean boInformBus, gboolean boInformMachine) +{ + NsmErrorStatus_e enStateMachineReturn = NsmErrorStatus_NotSet; + + if(boInformBus == TRUE) + { + NSMA_boSendSessionSignal(pstChangedSession); + } + + if(boInformMachine == TRUE) + { + enStateMachineReturn = NsmcSetData(NsmDataType_SessionState, (unsigned char*) pstChangedSession, sizeof(NsmSession_s)); + + if(enStateMachineReturn != NsmErrorStatus_Ok) + { + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to inform state machine about changed session state." ), + DLT_STRING(" State machine returned: "), DLT_INT( enStateMachineReturn ), + DLT_STRING(" Application: "), DLT_STRING(pstChangedSession->sOwner ), + DLT_STRING(" Session: "), DLT_STRING(pstChangedSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstChangedSession->enSeat ), + DLT_STRING(" Desired state: "), DLT_INT( pstChangedSession->enState)); + } + } +} + + +/********************************************************************************************************************** +* +* The function is called when the state of a product session should be changed. +* +* @param pstSession: Pointer to structure where session name, owner, seat and desired SessionState are defined. +* @param boInformBus: Defines whether a D-Bus signal should be send on session change. +* @param boInformMachine: Defines whether the StateMachine should be informed about session change. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetProductSessionState(NsmSession_s *pstSession, gboolean boInformBus, gboolean boInformMachine) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + GSList *pListEntry = NULL; + NsmSession_s *pExistingSession = NULL; + + g_mutex_lock(NSM__pSessionMutex); + + pListEntry = g_slist_find_custom(NSM__pSessions, pstSession, &NSM__i32SessionOwnerNameSeatCompare); + + if(pListEntry != NULL) + { + enRetVal = NsmErrorStatus_Ok; + pExistingSession = (NsmSession_s*) pListEntry->data; + + if(pExistingSession->enState != pstSession->enState) + { + pExistingSession->enState = pstSession->enState; + NSM__vPublishSessionChange(pExistingSession, boInformBus, boInformMachine); + } + } + else + { + enRetVal = NsmErrorStatus_WrongSession; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set session state. Session unknown."), + DLT_STRING(" Application: "), DLT_STRING(pstSession->sOwner ), + DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ), + DLT_STRING(" Desired state: "), DLT_INT( pstSession->enState)); + } + + g_mutex_unlock(NSM__pSessionMutex); + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called when the state of a default session should be changed. +* +* @param pstSession: Pointer to structure where session name, owner, seat and desired SessionState are defined. +* @param boInformBus: Defines whether a D-Bus signal should be send on session change. +* @param boInformMachine: Defines whether the StateMachine should be informed about session change. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetDefaultSessionState(NsmSession_s *pstSession, gboolean boInformBus, gboolean boInformMachine) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + GSList *pListEntry = NULL; + NsmSession_s *pExistingSession = NULL; + + /* Lock the sessions to be able to change them! */ + g_mutex_lock(NSM__pSessionMutex); + + pListEntry = g_slist_find_custom(NSM__pSessions, pstSession, &NSM__i32SessionNameSeatCompare); + + if(pListEntry != NULL) + { + pExistingSession = (NsmSession_s*) pListEntry->data; + + /* Check that the caller owns the session */ + if(g_strcmp0(pExistingSession->sOwner, pstSession->sOwner) == 0) + { + enRetVal = NsmErrorStatus_Ok; + + if(pExistingSession->enState != pstSession->enState) + { + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed default session's state."), + DLT_STRING(" Application: "), DLT_STRING(pExistingSession->sOwner ), + DLT_STRING(" Session: "), DLT_STRING(pExistingSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pExistingSession->enSeat ), + DLT_STRING(" Old state: "), DLT_INT( pExistingSession->enState), + DLT_STRING(" New state: "), DLT_INT( pstSession->enState )); + + pExistingSession->enState = pstSession->enState; + + NSM__vPublishSessionChange(pExistingSession, boInformBus, boInformMachine); + + if(pstSession->enState == NsmSessionState_Inactive) + { + g_strlcpy(pExistingSession->sOwner, NSM_DEFAULT_SESSION_OWNER, sizeof(pExistingSession->sOwner)); + } + } + } + else + { + /* The caller does not own the session. Check if he can become the owner. */ + if(g_strcmp0(pExistingSession->sOwner, NSM_DEFAULT_SESSION_OWNER) == 0) + { + /* The session has no owner. The new owner can obtain the session by setting it to an "active" state */ + if(pstSession->enState != NsmSessionState_Inactive) + { + /* The session has been activated. Overtake the owner. Broadcast new state. */ + enRetVal = NsmErrorStatus_Ok; + g_strlcpy(pExistingSession->sOwner, pstSession->sOwner, sizeof(pExistingSession->sOwner)); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed default session's state."), + DLT_STRING(" Application: "), DLT_STRING(pExistingSession->sOwner ), + DLT_STRING(" Session: "), DLT_STRING(pExistingSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pExistingSession->enSeat ), + DLT_STRING(" Old state: "), DLT_INT( pExistingSession->enState), + DLT_STRING(" New state: "), DLT_INT( pstSession->enState )); + + pExistingSession->enState = pstSession->enState; + + NSM__vPublishSessionChange(pExistingSession, boInformBus, boInformMachine); + } + else + { + /* The session has no owner, but could not be activated because the passed state is "inactive". */ + enRetVal = NsmErrorStatus_Parameter; + + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to enable default session. Passed state is 'inactive'. "), + DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ), + DLT_STRING(" Owning application: "), DLT_STRING(pExistingSession->sOwner ), + DLT_STRING(" Requesting application: "), DLT_STRING(pstSession->sOwner )); + } + } + else + { + /* The session owners do not match and the existing session has an owner */ + enRetVal = NsmErrorStatus_Error; + + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set default session state. Session has another owner."), + DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ), + DLT_STRING(" Owning application: "), DLT_STRING(pExistingSession->sOwner ), + DLT_STRING(" Requesting application: "), DLT_STRING(pstSession->sOwner )); + } + } + } + else + { + /* This should never happen, because the function is only called for default sessions! */ + enRetVal = NsmErrorStatus_Internal; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Critical error. Default session not found in session list!"), + DLT_STRING(" Application: "), DLT_STRING(pstSession->sOwner ), + DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ), + DLT_STRING(" Desired state: "), DLT_INT( pstSession->enState )); + } + + /* Unlock the sessions again. */ + g_mutex_unlock(NSM__pSessionMutex); + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called from IPC and StateMachine to set a session state. +* +* @param pstSession: Pointer to structure where session name, owner, seat and desired SessionState are defined. +* @param boInformBus: Defines whether a D-Bus signal should be send on session change. +* @param boInformMachine: Defines whether the StateMachine should be informed about session change. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetSessionState(NsmSession_s *pstSession, gboolean boInformBus, gboolean boInformMachine) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + + /* Check if the passed parameters are valid. */ + if( (g_strcmp0(pstSession->sOwner, NSM_DEFAULT_SESSION_OWNER) != 0) + && (pstSession->enState > NsmSessionState_Unregistered ) + && (pstSession->enSeat > NsmSeat_NotSet ) + && (pstSession->enSeat < NsmSeat_Last )) + { + /* Parameters are valid. Check if a platform session state is set */ + if(NSM__boIsPlatformSession(pstSession) == TRUE) + { + enRetVal = NSM__enSetDefaultSessionState(pstSession, boInformBus, boInformMachine); + } + else + { + enRetVal = NSM__enSetProductSessionState(pstSession, boInformBus, boInformMachine); + } + } + else + { + /* Error: An invalid parameter has been passed. */ + enRetVal = NsmErrorStatus_Parameter; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to change session state. Invalid paramter."), + DLT_STRING(" Application: "), DLT_STRING(pstSession->sOwner ), + DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat ), + DLT_STRING(" Desired state: "), DLT_INT( pstSession->enState )); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called from IPC and StateMachine to get the session state. +* +* @param pstSession: Pointer to structure where session name, owner and seat are defined and SessionState will be set. +* +* @return see NsmErrorStatus_e +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enGetSessionState(NsmSession_s *pstSession) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + NsmSession_s *pExistingSession = NULL; /* Pointer to existing session */ + GSList *pListEntry = NULL; + + g_mutex_lock(NSM__pSessionMutex); + + /* Search for session with name, seat and owner. */ + pListEntry = g_slist_find_custom(NSM__pSessions, pstSession, &NSM__i32SessionNameSeatCompare); + + if(pListEntry != NULL) + { + /* Found the session in the list. Return its state. */ + enRetVal = NsmErrorStatus_Ok; + pExistingSession = (NsmSession_s*) pListEntry->data; + pstSession->enState = pExistingSession->enState; + } + else + { + /* Error: The session is unknown. */ + enRetVal = NsmErrorStatus_WrongSession; + DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to retrieve session state. Unknown session."), + DLT_STRING(" Session: "), DLT_STRING(pstSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstSession->enSeat )); + } + + g_mutex_unlock(NSM__pSessionMutex); + + return enRetVal; +} + + +static void NSM__vFreeFailedApplicationObject(gpointer pFailedApplication) +{ + /* Function local variables. Cast the passed object */ + NSM__tstFailedApplication *pstFailedApplication = (NSM__tstFailedApplication*) pFailedApplication; + + g_free(pstFailedApplication); +} + + +/********************************************************************************************************************** +* +* The function is called either manually for one object or for every "session object", when the list of registered +* sessions is destroyed with "g_slist_free_full". All memory occupied by the "session object" is released. +* +* @param pSession: Pointer to the session object +* +* @return void +* +**********************************************************************************************************************/ +static void NSM__vFreeSessionObject(gpointer pSession) +{ + /* Function local variables. Cast the passed object */ + NsmSession_s *pstSession = (NsmSession_s*) pSession; + + /* Free the session object */ + g_free(pstSession); +} + + +/********************************************************************************************************************** +* +* The function is called either manually for one object or for every "lifecycle client object", when the list of +* registered lifecycle clients is destroyed with "g_slist_free_full". +* All memory occupied by the "lifecycle client object" is released. +* +* @param pLifecycleClient: Pointer to the lifecycle client object +* +* @return void +* +**********************************************************************************************************************/ +static void NSM__vFreeLifecycleClientObject(gpointer pLifecycleClient) +{ + /* Function local variables. Cast the passed object */ + NSM__tstLifecycleClient *pstLifecycleClient = (NSM__tstLifecycleClient*) pLifecycleClient; + + /* Free internal strings and objects */ + g_free(pstLifecycleClient->sBusName); + g_free(pstLifecycleClient->sObjName); + + /* No need to check for NULL. Only valid clients come here */ + NSMA_boFreeLcConsumerProxy(pstLifecycleClient->hClient); + + /* Free the shutdown client object */ + g_free(pstLifecycleClient); +} + + +/********************************************************************************************************************** +* +* The function is used to "custom compare" and identify a lifecycle client in the list of clients. +* Because the function is not used for sorting, the return value 1 is not used. +* +* @param pS1: Lifecycle client from list +* @param pS2: Lifecycle client to compare +* +* @return -1: pL1 < pL2 +* 0: pL1 = pL2 +* 1: pL1 > pL2 (unused, because function not used for sorting) +* +**********************************************************************************************************************/ +static gint NSM__i32LifecycleClientCompare(gconstpointer pL1, gconstpointer pL2) +{ + /* Function local variables. Cast the passed objects */ + NSM__tstLifecycleClient *pListClient = NULL; + NSM__tstLifecycleClient *pCompareClient = NULL; + gint i32RetVal = 1; + + pListClient = (NSM__tstLifecycleClient*) pL1; + pCompareClient = (NSM__tstLifecycleClient*) pL2; + + /* Compare the bus name of the client */ + if(g_strcmp0(pListClient->sBusName, pCompareClient->sBusName) == 0) + { + /* Bus names are equal. Now compare object name */ + if(g_strcmp0(pListClient->sObjName, pCompareClient->sObjName) == 0) + { + i32RetVal = 0; /* Clients are identical. Return 0. */ + } + else + { + i32RetVal = -1; /* Object names are different. Return -1. */ + } + } + else + { + i32RetVal = -1; /* Bus names are different. Return -1. */ + } + + return i32RetVal; /* Return result of comparison. */ +} + + +/********************************************************************************************************************** +* +* The function is used to "custom compare" and identify a session in the list of sessions. +* It compares the "session name", the "session owner" and "seat". +* Because the function is not used for sorting, the return value 1 is not used. +* +* @param pS1: Session from list +* @param pS2: Session to compare +* +* @return -1: pS1 < pS2 +* 0: pS1 = pS2 +* 1: pS1 > pS2 (unused, because function not used for sorting) +* +**********************************************************************************************************************/ +static gint NSM__i32SessionOwnerNameSeatCompare(gconstpointer pS1, gconstpointer pS2) +{ + /* Function local variables. Cast the passed objects */ + NsmSession_s *pListSession = NULL; + NsmSession_s *pSearchSession = NULL; + gint i32RetVal = 1; + + pListSession = (NsmSession_s*) pS1; + pSearchSession = (NsmSession_s*) pS2; + + if(g_strcmp0(pListSession->sOwner, pSearchSession->sOwner) == 0) + { + i32RetVal = NSM__i32SessionNameSeatCompare(pS1, pS2); + } + else + { + i32RetVal = -1; /* Session owners differ. Return -1. */ + } + + return i32RetVal; /* Return result of comparison */ +} + + +/********************************************************************************************************************** +* +* The function is used to "custom compare" and identify a session in the list of sessions. +* It compares the "session name" and "seat". +* Because the function is not used for sorting, the return value 1 is not used. +* +* @param pS1: Session from list +* @param pS2: Session to compare +* +* @return -1: pS1 < pS2 +* 0: pS1 = pS2 +* 1: pS1 > pS2 (unused, because function not used for sorting) +* +**********************************************************************************************************************/ +static gint NSM__i32SessionNameSeatCompare(gconstpointer pS1, gconstpointer pS2) +{ + /* Function local variables. Cast the passed objects */ + NsmSession_s *pListSession = NULL; + NsmSession_s *pSearchSession = NULL; + gint i32RetVal = 1; + + pListSession = (NsmSession_s*) pS1; + pSearchSession = (NsmSession_s*) pS2; + + /* Compare seats of the sessions. */ + if(pListSession->enSeat == pSearchSession->enSeat) + { + /* Seats are equal. Compare session names. */ + if(g_strcmp0(pListSession->sName, pSearchSession->sName) == 0) + { + i32RetVal = 0; /* Session are equal. Return 0. */ + } + else + { + i32RetVal = -1; /* Session names differ. Return -1. */ + } + } + else + { + i32RetVal = -1; /* Session seats differ. Return -1. */ + } + + return i32RetVal; +} + + +/********************************************************************************************************************** +* +* The function is used to "custom compare" and identify an application name. +* Because the function is not used for sorting, the return value 1 is not used. +* +* @param pA1: Application object from list +* @param pA2: Application object to compare +* +* @return -1: pA1 < pA2 +* 0: pA1 = pA2 +* 1: pA1 > pA2 (unused, because function not used for sorting) +* +**********************************************************************************************************************/ +static gint NSM__i32ApplicationCompare(gconstpointer pA1, gconstpointer pA2) +{ + /* Function local variables. Cast the passed objects */ + NSM__tstFailedApplication *pListApp = NULL; + NSM__tstFailedApplication *pSearchApp = NULL; + gint i32RetVal = 1; + + pListApp = (NSM__tstFailedApplication*) pA1; + pSearchApp = (NSM__tstFailedApplication*) pA2; + + /* Compare names of the applications */ + if(g_strcmp0(pListApp->sName, pSearchApp->sName) == 0) + { + i32RetVal = 0; /* Names are equal. Return 0. */ + } + else + { + i32RetVal = -1; /* Names are different. Return -1. */ + } + + return i32RetVal; /* Return result of comparison */ +} + + +/********************************************************************************************************************** +* +* The function is used to "custom compare" and identify a session with a special owner. +* Because the function is not used for sorting, the return value 1 is not used. +* +* @param pS1: Session from list +* @param pS2: Session to compare +* +* @return -1: pS1 < pS2 +* 0: pS1 = pS2 +* 1: pS1 > pS2 (unused, because function not used for sorting) +* +**********************************************************************************************************************/ +static gint NSM__i32SessionOwnerCompare(gconstpointer pS1, gconstpointer pS2) +{ + /* Function local variables. Cast the passed objects */ + NsmSession_s *pListSession = NULL; + NsmSession_s *pSearchSession = NULL; + gint i32RetVal = 1; + + pListSession = (NsmSession_s*) pS1; + pSearchSession = (NsmSession_s*) pS2; + + /* Compare owners of the sessions */ + if(g_strcmp0(pListSession->sOwner, pSearchSession->sOwner) == 0) + { + i32RetVal = 0; /* Owners are equal. Return 0. */ + } + else + { + i32RetVal = -1; /* Owners are different. Return -1. */ + } + + return i32RetVal; /* Return result of comparison */ +} + + +/********************************************************************************************************************** +* +* The function is called after a lifecycle client was informed about the changed life cycle. +* The return value of the last informed client will be evaluated and the next lifecycle client +* to inform will be determined and called. +* If there is no client left, the lifecycle sequence will be finished. +* +* @param pSrcObject: Source object (lifecycle client proxy) +* @param pRes: Result of asynchronous call +* @param pUserData: Pointer to the current lifecycle client object +* +* @return void +* +**********************************************************************************************************************/ +static void NSM__vOnLifecycleRequestFinish(const NsmErrorStatus_e enErrorStatus) +{ + if(enErrorStatus == NsmErrorStatus_Ok) + { + /* The clients "LifecycleRequest" has been successfully processed. */ + NSM__vLtProf(NSM__pCurrentLifecycleClient->sBusName, NSM__pCurrentLifecycleClient->sObjName, 0, "leave: ", 0); + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Successfully called lifecycle client.")); + } + else + { + /* Error: The method of the lifecycle client returned an error */ + NSM__vLtProf(NSM__pCurrentLifecycleClient->sBusName, NSM__pCurrentLifecycleClient->sObjName, 0, "leave: error: ", enErrorStatus); + DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to call life cycle client." ), + DLT_STRING(" Return Value: "), DLT_INT((gint) enErrorStatus)); + } + + NSM__vCallNextLifecycleClient(); +} + + +/********************************************************************************************************************** +* +* The function is called when: +* - The NodeState changes (NSM__boHandleSetNodeState), to initiate a lifecycle sequence +* - A client returned and the next client has to be called (NSM__vOnLifecycleRequestFinish) +* +* If the clients need to "run up" or shut down for the current NodeState, the function +* searches the list forward or backward until a client is found, which needs to be informed. +* +* PLEASE NOTE: If all clients have been informed about a "shut down", this function will quit the +* "g_main_loop", which leads to the the termination of the NSM! +* +* @return void +* +**********************************************************************************************************************/ +static void NSM__vCallNextLifecycleClient(void) +{ + /* Function local variables */ + GList *pListEntry = NULL; /* Iterate through list entries */ + NSM__tstLifecycleClient *pClient = NULL; /* Client object from list */ + guint32 u32ShutdownType = NSM_SHUTDOWNTYPE_NOT; /* Return value */ + gboolean boShutdown = FALSE; + + NSM__pCurrentLifecycleClient = NULL; + + g_mutex_lock(NSM__pNodeStateMutex); + + /* Based on NodeState determine if clients have to shutdown or run up. Find a client that has not been informed */ + switch(NSM__enNodeState) + { + /* For "shutdown" search backward in the list, until there is a client that has not been shut down */ + case NsmNodeState_ShuttingDown: + u32ShutdownType = NSM_SHUTDOWNTYPE_NORMAL; + for( pListEntry = g_list_last(NSM__pLifecycleClients); + (pListEntry != NULL) && (NSM__pCurrentLifecycleClient == NULL); + pListEntry = g_list_previous(pListEntry)) + { + /* Check if client has not been shut down and is registered for "normal shutdown" */ + pClient = (NSM__tstLifecycleClient*) pListEntry->data; + if( ( pClient->boShutdown == FALSE) + && ( (pClient->u32RegisteredMode & u32ShutdownType) != 0 )) + { + /* Found a "running" previous client, registered for the shutdown mode */ + NSM__pCurrentLifecycleClient = (NSM__tstLifecycleClient*) pListEntry->data; + } + } + break; + + /* For "fast shutdown" search backward in the list, until there is a client that has not been shut down */ + case NsmNodeState_FastShutdown: + u32ShutdownType = NSM_SHUTDOWNTYPE_FAST; + for( pListEntry = g_list_last(NSM__pLifecycleClients); + (pListEntry != NULL) && (NSM__pCurrentLifecycleClient == NULL); + pListEntry = g_list_previous(pListEntry)) + { + /* Check if client has not been shut down and is registered for "fast shutdown" */ + pClient = (NSM__tstLifecycleClient*) pListEntry->data; + if( ( pClient->boShutdown == FALSE) + && ( (pClient->u32RegisteredMode & u32ShutdownType) != 0 )) + { + /* Found a "running" previous client, registered for the shutdown mode */ + NSM__pCurrentLifecycleClient = (NSM__tstLifecycleClient*) pListEntry->data; + } + } + break; + + /* For a "running" mode search forward in the list (get next), until there is a client that is shut down */ + default: + u32ShutdownType = NSM_SHUTDOWNTYPE_RUNUP; + for(pListEntry = g_list_first(NSM__pLifecycleClients); + (pListEntry != NULL) && (NSM__pCurrentLifecycleClient == NULL); + pListEntry = g_list_next(pListEntry)) + { + /* Check if client is shut down */ + pClient = (NSM__tstLifecycleClient*) pListEntry->data; + if(pClient->boShutdown == TRUE) + { + /* The client was shutdown. It should run up, because we are in a running mode */ + NSM__pCurrentLifecycleClient = (NSM__tstLifecycleClient*) pListEntry->data; + } + } + break; + } + + /* Check if a client could be found that needs to be informed */ + if(NSM__pCurrentLifecycleClient != NULL) + { + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Call lifecycle client." ), + DLT_STRING(" Bus name: "), DLT_STRING(NSM__pCurrentLifecycleClient->sBusName ), + DLT_STRING(" Obj name: "), DLT_STRING(NSM__pCurrentLifecycleClient->sObjName ), + DLT_STRING(" Registered types: "), DLT_INT(NSM__pCurrentLifecycleClient->u32RegisteredMode), + DLT_STRING(" Client: "), DLT_INT( (guint) NSM__pCurrentLifecycleClient->hClient ), + DLT_STRING(" ShutdownType: "), DLT_UINT(u32ShutdownType )); + + /* Remember that client received a run-up or shutdown call */ + pClient->boShutdown = (u32ShutdownType != NSM_SHUTDOWNTYPE_RUNUP); + + NSM__vLtProf(NSM__pCurrentLifecycleClient->sBusName, NSM__pCurrentLifecycleClient->sObjName, u32ShutdownType, "enter: ", 0); + + NSMA_boCallLcClientRequest(NSM__pCurrentLifecycleClient->hClient, u32ShutdownType); + boShutdown = FALSE; + } + else + { + /* The last client was called. Depending on the NodeState check if we can end. */ + switch(NSM__enNodeState) + { + /* All registered clients have been 'fast shutdown'. Set NodeState to "shutdown" */ + case NsmNodeState_FastShutdown: + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Informed all registered clients about 'fast shutdown'. Set NodeState to 'shutdown'")); + + NSM__enNodeState = NsmNodeState_Shutdown; + NsmcSetData(NsmDataType_NodeState, (unsigned char*) &NSM__enNodeState, sizeof(NsmNodeState_e)); + NSMA_boSendNodeStateSignal(NSM__enNodeState); + boShutdown = TRUE; + break; + + /* All registered clients have been 'shutdown'. Set NodeState to "shutdown" */ + case NsmNodeState_ShuttingDown: + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Informed all registered clients about 'shutdown'. Set NodeState to 'shutdown'.")); + + NSM__enNodeState = NsmNodeState_Shutdown; + NsmcSetData(NsmDataType_NodeState, (unsigned char*) &NSM__enNodeState, sizeof(NsmNodeState_e)); + NSMA_boSendNodeStateSignal(NSM__enNodeState); + boShutdown = TRUE; + break; + + /* We are in a running state. Nothing to do */ + default: + boShutdown = FALSE; + break; + } + } + + g_mutex_unlock(NSM__pNodeStateMutex); + + if(boShutdown == TRUE) + { + NSMA_boQuitEventLoop(); + } +} + + +/********************************************************************************************************************** +* +* The callback is called when a check for LUC is required. +* It uses the NodeStateMachine to determine whether LUC is required. +* +* @param pboRetVal: Pointer, where to store the StateMAchine's return value +* +**********************************************************************************************************************/ +static gboolean NSM__boOnHandleCheckLucRequired(void) +{ + /* Determine if LUC is required by asking the NodeStateMachine */ + return (NsmcLucRequired() == 0x01) ? TRUE : FALSE; +} + + +/********************************************************************************************************************** +* +* The callback is called when the "boot mode" should be set. +* It sets the BootMode using an internal function. +* +* @param i32BootMode: New boot mode +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleSetBootMode(const gint i32BootMode) +{ + /* Use internal setter to set the BootMode and inform the StateMachine */ + return NSM__enSetBootMode(i32BootMode, TRUE); +} + + +/********************************************************************************************************************** +* +* The callback is called when the "node state" should be set. +* It sets the NodeState using an internal function. +* +* @param enNodeStateId: New node state +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleSetNodeState(const NsmNodeState_e enNodeState) +{ + return NSM__enSetNodeState(enNodeState, TRUE, TRUE); +} + + +/********************************************************************************************************************** +* +* The callback is called when the "application mode" should be set. +* It sets the ApplicationMode using an internal function. +* +* @param enApplicationModeId: New application mode +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleSetApplicationMode(const NsmApplicationMode_e enApplMode) +{ + return NSM__enSetApplicationMode(enApplMode, TRUE, TRUE); +} + + +/********************************************************************************************************************** +* +* The callback is called when the node reset is requested. +* It passes the request to the NodestateMachine. +* +* @param i32RestartReason: Restart reason +* @param i32RestartType: Restart type +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleRequestNodeRestart(const NsmRestartReason_e enRestartReason, + const guint u32RestartType) +{ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Node restart has been requested.")); + + if(NsmcRequestNodeRestart() == 0x01) + { + enRetVal = NsmErrorStatus_Ok; + (void) NSMA_boSetRestartReason(enRestartReason); + } + else + { + enRetVal = NsmErrorStatus_Error; + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The called is called when a new session should be registered. +* It checks the passed parameters and creates a NsmSession_s structure of them. +* If everything is ok, the new session will be created and the system and StateMachine will be informed. +* +* @param sSessionName: Name of the new session +* @param sSessionOwner: Owner of the new session +* @param enSeatId: Seat which belongs to the new session +* @param enSessionState: Initial state of the new session +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleRegisterSession(const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId, + const NsmSessionState_e enSessionState) +{ + /* Function local variables */ + NsmSession_s *pNewSession = NULL; /* Pointer to new created session */ + GSList *pListEntry = NULL; /* Pointer to list entry */ + size_t u32SessionNameLen = 0; /* Length of passed session owner */ + size_t u32SessionOwnerLen = 0; /* Length of passed session name */ + NsmSession_s stSearchSession; /* To search for existing session */ + gboolean boOwnerValid = FALSE; + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + /* Initialize variables */ + memset(&stSearchSession, 0, sizeof(stSearchSession)); + + /* Check if the passed parameters are valid */ + u32SessionNameLen = strlen(sSessionName); + u32SessionOwnerLen = strlen(sSessionOwner); + boOwnerValid = (g_strcmp0(sSessionOwner, NSM_DEFAULT_SESSION_OWNER) != 0); + + if( (boOwnerValid == TRUE ) + && (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH ) + && (u32SessionOwnerLen < NSM_MAX_SESSION_OWNER_LENGTH) + && (enSeatId > NsmSeat_NotSet ) + && (enSeatId < NsmSeat_Last ) + && (enSessionState > NsmSessionState_Unregistered)) + { + /* 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_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 )); + } + } + 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 )); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The callback is called when a session should be unregistered. +* It checks the passed parameters and creates a NsmSession_s structure of them. +* If everything is ok, the new session will be removed and the system and StateMachine will be informed. +* +* @param sSessionName: Name of the new session that should be unregistered. +* @param sSessionOwner: Current owner of the session that should be unregistered. +* @param enSeat: Seat for which the session should be unregistered. +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleUnRegisterSession(const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId) +{ + /* Function local variables */ + NsmSession_s *pExistingSession = NULL; /* Pointer to existing session */ + GSList *pListEntry = NULL; /* Pointer to list entry */ + size_t u32SessionNameLen = 0; /* Length of passed session owner */ + size_t u32SessionOwnerLen = 0; /* Length of passed session name */ + NsmSession_s stSearchSession; /* To search for existing session */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + /* Initialize variables */ + memset(&stSearchSession, 0, sizeof(stSearchSession)); + + /* Check if the passed parameters are valid */ + u32SessionNameLen = strlen(sSessionName); + u32SessionOwnerLen = strlen(sSessionOwner); + + if( (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH ) + && (u32SessionOwnerLen < NSM_MAX_SESSION_OWNER_LENGTH)) + { + /* Assign seat, session name and owner to search for session */ + stSearchSession.enSeat = enSeatId; + 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 )); + } + } + else + { + /* Error: Invalid parameter. The session or owner name is to long. */ + enRetVal = NsmErrorStatus_Parameter; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to unregister session. The session or owner name is to long."), + DLT_STRING(" Name: " ), DLT_STRING(sSessionName ), + DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ), + DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId )); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The callback is called when a lifecycle client should be registered. +* In the list of lifecycle clients it will be checked if the client already exists. +* If it exists, it's settings will be updated. Otherwise a new client will be created. +* +* @param sBusName: Bus name of the remote application that hosts the lifecycle client interface +* @param sObjName: Object name of the lifecycle client +* @param u32ShutdownMode: Shutdown mode for which the client wants to be informed +* @param u32TimeoutMs: Timeout in ms. If the client does not return after the specified time, the NSM +* aborts its shutdown and calls the next client. +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleRegisterLifecycleClient(const gchar *sBusName, + const gchar *sObjName, + const guint u32ShutdownMode, + const guint u32TimeoutMs) +{ + NSM__tstLifecycleClient stTestLifecycleClient = {0}; + NSM__tstLifecycleClient *pstNewClient = NULL; + NSM__tstLifecycleClient *pstExistingClient = NULL; + GList *pListEntry = NULL; + NSMA_tLcConsumerHandle *hConsumer = NULL; + GError *pError = NULL; + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + /* The parameters are valid. Create a temporary client to search the list */ + stTestLifecycleClient.sBusName = (gchar*) sBusName; + stTestLifecycleClient.sObjName = (gchar*) sObjName; + + /* Check if the lifecycle client already is registered */ + pListEntry = g_list_find_custom(NSM__pLifecycleClients, &stTestLifecycleClient, &NSM__i32LifecycleClientCompare); + + if(pListEntry == NULL) + { + /* The client does not exist. Try to create a new proxy */ + hConsumer = NSMA_hCreateLcConsumer(sBusName, sObjName, u32TimeoutMs); + + /* The new proxy could be created. Create and store new client */ + if(hConsumer != NULL) + { + enRetVal = NsmErrorStatus_Ok; + + /* Create client object and copies of the strings. */ + pstNewClient = g_new0(NSM__tstLifecycleClient, 1); + pstNewClient->u32RegisteredMode = u32ShutdownMode; + pstNewClient->sBusName = g_strdup(sBusName); + pstNewClient->sObjName = g_strdup(sObjName); + pstNewClient->boShutdown = FALSE; + pstNewClient->hClient = hConsumer; + + + /* Append the new client to the list */ + NSM__pLifecycleClients = g_list_append(NSM__pLifecycleClients, pstNewClient); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Registered new lifecycle consumer." ), + DLT_STRING(" Bus name: "), DLT_STRING(pstNewClient->sBusName ), + DLT_STRING(" Obj name: "), DLT_STRING(pstNewClient->sObjName ), + DLT_STRING(" Timeout: " ), DLT_UINT( u32TimeoutMs ), + DLT_STRING(" Mode(s): "), DLT_INT( pstNewClient->u32RegisteredMode), + DLT_STRING(" Client: "), DLT_UINT((guint) pstNewClient->hClient )); + } + else + { + enRetVal = NsmErrorStatus_Dbus; + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Failed to register new lifecycle consumer. D-Bus error."), + DLT_STRING(" Bus name: "), DLT_STRING(sBusName ), + DLT_STRING(" Obj name: "), DLT_STRING(sObjName ), + DLT_STRING(" Timeout: " ), DLT_UINT( u32TimeoutMs ), + DLT_STRING(" Registered mode(s): "), DLT_INT( u32ShutdownMode ), + DLT_STRING(" Error: "), DLT_STRING(pError->message )); + + g_error_free(pError); + } + } + else + { + /* The client already exists. Assert to update the values for timeout and mode */ + enRetVal = NsmErrorStatus_Ok; + pstExistingClient = (NSM__tstLifecycleClient*) pListEntry->data; + pstExistingClient->u32RegisteredMode |= u32ShutdownMode; + NSMA_boSetLcClientTimeout(pstExistingClient->hClient, u32TimeoutMs); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Changed lifecycle consumer registration." ), + DLT_STRING(" Bus name: "), DLT_STRING(pstExistingClient->sBusName ), + DLT_STRING(" Obj name: "), DLT_STRING(pstExistingClient->sObjName ), + DLT_STRING(" Timeout: " ), DLT_UINT( u32TimeoutMs ), + DLT_STRING(" Registered mode(s): "), DLT_INT( pstExistingClient->u32RegisteredMode)); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The callback is called when a lifecycle client should be unregistered or a shutdown +* mode should be removed. In the list of lifecycle clients will be checked if the client exists. If the +* client is found, the registration for the passed shutdown modes will be removed. If the client finally +* is not registered for any shutdown mode, its entry will be removed from the list. +* +* @param sBusName: Bus name of the remote application that hosts the lifecycle client interface +* @param sObjName: Object name of the lifecycle client +* @param u32ShutdownMode: Shutdown mode for which the client wants to unregister +* @param penRetVal: Pointer, where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleUnRegisterLifecycleClient(const gchar *sBusName, + const gchar *sObjName, + const guint u32ShutdownMode) +{ + NSM__tstLifecycleClient *pstExistingClient = NULL; + NSM__tstLifecycleClient stSearchClient = {0}; + GList *pListEntry = NULL; + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + stSearchClient.sBusName = (gchar*) sBusName; + stSearchClient.sObjName = (gchar*) sObjName; + + /* Check if the lifecycle client already is registered */ + pListEntry = g_list_find_custom(NSM__pLifecycleClients, &stSearchClient, &NSM__i32LifecycleClientCompare); + + /* Check if an existing client could be found */ + if(pListEntry != NULL) + { + /* The client could be found in the list. Change the registered shutdown mode */ + enRetVal = NsmErrorStatus_Ok; + pstExistingClient = (NSM__tstLifecycleClient*) pListEntry->data; + pstExistingClient->u32RegisteredMode &= ~(u32ShutdownMode); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Unregistered lifecycle consumer for mode(s)." ), + DLT_STRING(" Bus name: "), DLT_STRING(pstExistingClient->sBusName ), + DLT_STRING(" Obj name: "), DLT_STRING(pstExistingClient->sObjName ), + DLT_STRING(" New mode: "), DLT_INT( pstExistingClient->u32RegisteredMode), + DLT_STRING(" Client: " ), DLT_UINT((guint) pstExistingClient->hClient) ); + + if(pstExistingClient->u32RegisteredMode == NSM_SHUTDOWNTYPE_NOT) + { + /* The client is not registered for at least one mode. Remove it from the list */ + NSM__vFreeLifecycleClientObject(pstExistingClient); + NSM__pLifecycleClients = g_list_remove(NSM__pLifecycleClients, pstExistingClient); + } + } + else + { + /* Warning: The client could not be found in the list of clients. */ + enRetVal = NsmErrorStatus_Parameter; + DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to unregister lifecycle consumer."), + DLT_STRING(" Bus name: "), DLT_STRING(sBusName), + DLT_STRING(" Obj name: "), DLT_STRING(sObjName), + DLT_STRING(" Unregistered mode(s): "), DLT_INT( u32ShutdownMode)); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is used to get the state of the passed session. +* It checks the passed parameters and creates a NsmSession_s structure of them. +* If everything is ok, the state of the session will be determined and written to penSessionState. +* +* @param sSessionName: Name of the session whose state just be returned +* @param sSessionName: Owner of the session whose state just be returned +* @param enSeatId: Seat of the session +* @param penSessionState: Pointer where to store the session state +* @param penRetVal: Pointer where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleGetSessionState(const gchar *sSessionName, + const NsmSeat_e enSeatId, + NsmSessionState_e *penSessionState) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + size_t u32SessionNameLen = 0; /* Length of passed session owner */ + NsmSession_s stSearchSession; /* To search for existing session */ + + /* Initialize variables */ + memset(&stSearchSession, 0, sizeof(stSearchSession)); + + /* Check if the passed parameters are valid */ + u32SessionNameLen = strlen(sSessionName); + + if(u32SessionNameLen < NSM_MAX_SESSION_OWNER_LENGTH) + { + /* Search for session with name, seat and owner. */ + stSearchSession.enSeat = enSeatId; + g_strlcpy((gchar*) stSearchSession.sName, sSessionName, sizeof(stSearchSession.sName) ); + + enRetVal = NSM__enGetSessionState(&stSearchSession); + *penSessionState = stSearchSession.enState; + } + else + { + /* Error: Invalid parameter. The session or owner name is to long. */ + enRetVal = NsmErrorStatus_Parameter; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to get session state. The session name is to long."), + DLT_STRING(" Name: " ), DLT_STRING(sSessionName ), + DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId )); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function sets the state of a session to a passed value. +* It checks the passed parameters and creates a NsmSession_s structure of them. +* If everything is ok, the state of the session will be set accordingly. +* +* @param sSessionName: Name of the session whose state just be set +* @param sSessionOwner: Owner of the session +* @param enSeatId: Seat of the session +* @param enSessionState: New state of the session +* @param penRetVal: Pointer where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleSetSessionState(const gchar *sSessionName, + const gchar *sSessionOwner, + const NsmSeat_e enSeatId, + const NsmSessionState_e enSessionState) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + size_t u32SessionNameLen = 0; /* Length of passed session owner */ + size_t u32SessionOwnerLen = 0; /* Length of passed session name */ + NsmSession_s stSession; /* Session object passed to internal function */ + + /* Initialize variables */ + memset(&stSession, 0, sizeof(stSession)); + + /* Check if the passed parameters are valid */ + u32SessionNameLen = strlen(sSessionName); + u32SessionOwnerLen = strlen(sSessionOwner); + + if( (u32SessionNameLen < NSM_MAX_SESSION_NAME_LENGTH ) + && (u32SessionOwnerLen < NSM_MAX_SESSION_OWNER_LENGTH)) + { + /* Build session object to pass it internally */ + g_strlcpy((gchar*) stSession.sName, sSessionName, sizeof(stSession.sName) ); + g_strlcpy((gchar*) stSession.sOwner, sSessionOwner, sizeof(stSession.sOwner)); + + stSession.enSeat = enSeatId; + stSession.enState = enSessionState; + + enRetVal = NSM__enSetSessionState(&stSession, TRUE, TRUE); + } + else + { + /* Error: Invalid parameter. The session or owner name is to long. */ + enRetVal = NsmErrorStatus_Parameter; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set session state. Invalid parameter."), + DLT_STRING(" Name: " ), DLT_STRING(sSessionName ), + DLT_STRING(" Owner: " ), DLT_STRING(sSessionOwner ), + DLT_STRING(" Seat: " ), DLT_INT((gint) enSeatId )); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The helper function is called by 'NSM__boOnHandleSetAppHealthStatus', when an application became valid again. +* It removes the application from the list of invalid apps. +* +* @param pstFailedApp: Pointer to structure with information about the failed application. +* +* @return NsmErrorStatus_Ok: The application has been removed from the list of failed apps. +* NsmErrorStatus_WrongSession: The application has never been on the list of failed apps. +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetAppStateValid(NSM__tstFailedApplication* pstFailedApp) +{ + /* Function local variables */ + GSList *pAppListEntry = NULL; /* List entry of application */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + NSM__tstFailedApplication *pstExistingApplication = NULL; + + /* An application has become valid again. Check if it really was invalid before. */ + pAppListEntry = g_slist_find_custom(NSM__pFailedApplications, pstFailedApp, &NSM__i32ApplicationCompare); + + if(pAppListEntry != NULL) + { + /* We found at least one entry for the application. Remove it from the list */ + enRetVal = NsmErrorStatus_Ok; + pstExistingApplication = (NSM__tstFailedApplication*) pAppListEntry->data; + NSM__pFailedApplications = g_slist_remove(NSM__pFailedApplications, pstExistingApplication); + NSM__vFreeFailedApplicationObject(pstExistingApplication); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: An application has become valid again." ), + DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName)); + } + else + { + /* Error: There was no session registered for the application that failed. */ + enRetVal = NsmErrorStatus_Error; + DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: Failed to set application valid. Application was never invalid."), + DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName )); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The helper function is called by 'NSM__enSetAppStateFailed', when an application failed. +* It looks for sessions that have been registered by the app. +* +* @param pstFailedApp: Pointer to structure with information about the failed application. +* +**********************************************************************************************************************/ +static void NSM__vDisableSessionsForApp(NSM__tstFailedApplication* pstFailedApp) +{ + /* Function local variables */ + GSList *pSessionListEntry = NULL; + NsmSession_s *pstExistingSession = NULL; + NsmSession_s stSearchSession; + + /* Initialize variables */ + memset(&stSearchSession, 0, sizeof(stSearchSession)); + + /* Only set the "owner" of the session (to the AppName) to search for all sessions of the app. */ + g_strlcpy(stSearchSession.sOwner, pstFailedApp->sName, sizeof(stSearchSession.sOwner)); + + g_mutex_lock(NSM__pSessionMutex); + pSessionListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionOwnerCompare); + + if(pSessionListEntry != NULL) + { + /* Found at least one session. */ + do + { + /* Get the session object for the list entry */ + pstExistingSession = (NsmSession_s*) pSessionListEntry->data; + pstExistingSession->enState = NsmSessionState_Unregistered; + + /* Inform D-Bus and StateMachine that a session became invalid */ + NSM__vPublishSessionChange(pstExistingSession, TRUE, TRUE); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: A session has become invalid, because an application failed."), + DLT_STRING(" Application: "), DLT_STRING(pstExistingSession->sOwner ), + DLT_STRING(" Session: "), DLT_STRING(pstExistingSession->sName ), + DLT_STRING(" Seat: "), DLT_INT( pstExistingSession->enSeat ), + DLT_STRING(" State: "), DLT_INT( pstExistingSession->enState )); + + /* Remove or "reset" session */ + if(NSM__boIsPlatformSession(pstExistingSession) == TRUE) + { + /* It is a default session. Don't remove it. Set owner to NSM again. */ + g_strlcpy(pstExistingSession->sOwner, NSM_DEFAULT_SESSION_OWNER, sizeof(pstExistingSession->sOwner)); + } + else + { + /* The session has been registered by a failed app. Remove it. */ + NSM__pSessions = g_slist_remove(NSM__pSessions, pstExistingSession); + NSM__vFreeSessionObject(pstExistingSession); + } + + /* Try to find the next session that had been registered for the app. */ + pSessionListEntry = g_slist_find_custom(NSM__pSessions, &stSearchSession, &NSM__i32SessionOwnerCompare); + + } while(pSessionListEntry != NULL); + } + else + { + /* There have been no session registered for this application. */ + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: There had been no registered sessions." ), + DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName)); + } + + g_mutex_unlock(NSM__pSessionMutex); +} + + +/********************************************************************************************************************** +* +* The helper function is called by 'NSM__boOnHandleSetAppHealthStatus', when an application failed. +* +* @param pstFailedApp: Pointer to structure with information about the failed application. +* +* @return always "NsmErrorStatus_Ok" +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enSetAppStateFailed(NSM__tstFailedApplication* pstFailedApp) +{ + /* Function local variables */ + GSList *pFailedAppListEntry = NULL; /* List entry of application */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + NSM__tstFailedApplication *pstFailedApplication = NULL; + + /* An application failed. Check if the application already is known as 'failed'. */ + pFailedAppListEntry = g_slist_find_custom(NSM__pFailedApplications, pstFailedApp, &NSM__i32ApplicationCompare); + + if(pFailedAppListEntry == NULL) + { + /* The application is not on the list yet. Create it. */ + enRetVal = NsmErrorStatus_Ok; + + pstFailedApplication = g_new(NSM__tstFailedApplication, 1); + g_strlcpy(pstFailedApplication->sName, pstFailedApp->sName, sizeof(pstFailedApplication->sName)); + NSM__pFailedApplications = g_slist_append(NSM__pFailedApplications, pstFailedApplication); + + /* Disable all session that have been registered by the application */ + NSM__vDisableSessionsForApp(pstFailedApplication); + } + else + { + /* Warning: The application is already in the list of failed session. */ + enRetVal = NsmErrorStatus_Ok; + DLT_LOG(NsmContext, DLT_LOG_WARN, DLT_STRING("NSM: The application has already been marked as 'failed'."), + DLT_STRING(" Application: "), DLT_STRING(pstFailedApp->sName )); + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function is called when an application has become invalid or valid again. +* If an application became inactive, it will be added to the list of failed applications +* and signals for the session registered by the application will be emitted. +* If an application became valid again, it will only be removed from the list of failed sessions. +* +* @param sAppName: Application which changed its state. +* @param boAppState: Indicates if the application became invalid or valid again. +* @param penRetVal: Pointer where to store the return value +* +**********************************************************************************************************************/ +static NsmErrorStatus_e NSM__enOnHandleSetAppHealthStatus(const gchar *sAppName, + const gboolean boAppState) +{ + /* Function local variables */ + NSM__tstFailedApplication stSearchApplication; /* Temporary application object for search */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; + + /* Initialize variables */ + memset(&stSearchApplication, 0, sizeof(stSearchApplication)); + + /* Check if passed parameters are valid */ + if(strlen(sAppName) < NSM_MAX_SESSION_OWNER_LENGTH) + { + /* The application name is valid. Copy it for further checks. */ + g_strlcpy((gchar*) stSearchApplication.sName, sAppName, sizeof(stSearchApplication.sName)); + + if(boAppState == TRUE) + { + enRetVal = NSM__enSetAppStateValid(&stSearchApplication); + } + else + { + enRetVal = NSM__enSetAppStateFailed(&stSearchApplication); + } + } + else + { + /* Error: The passed application name is too long. */ + enRetVal = NsmErrorStatus_Parameter; + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Failed to set application health status. The application name is too long."), + DLT_STRING(" Owner: " ), DLT_STRING(sAppName ), + DLT_STRING(" State: " ), DLT_INT(boAppState )); + + } + + return enRetVal; +} + + +/********************************************************************************************************************** +* +* The function returns the current AppHealthCount, which is stored in local variable. +* +* @param pu32AppHealthCount: Pointer where to store the AppHealthCount (number of failed applications). +* +**********************************************************************************************************************/ +static guint NSM__u32OnHandleGetAppHealthCount(void) +{ + return g_slist_length(NSM__pFailedApplications); +} + + +/********************************************************************************************************************** +* +* The function returns the current interface version of the NodeStateManager. +* +* @param pu32InterfaceVersion: Pointer where to store the interface version. +* +**********************************************************************************************************************/ +static guint NSM__u32OnHandleGetInterfaceVersion(void) +{ + /* Return interface version to caller. */ + return NSM_INTERFACE_VERSION; +} + + +/********************************************************************************************************************** +* +* The function initializes all file local variables +* +**********************************************************************************************************************/ +static void NSM__vInitializeVariables(void) +{ + /* Initialize file local variables */ + NSM__pSessionMutex = NULL; + NSM__pSessions = NULL; + NSM__pLifecycleClients = NULL; + NSM__pNodeStateMutex = NULL; + NSM__enNodeState = NsmNodeState_NotSet; + NSM__pApplicationModeMutex = NULL; + NSM__enApplicationMode = NsmApplicationMode_NotSet; + NSM__pFailedApplications = NULL; + NSM__pCurrentLifecycleClient = NULL; +} + + +/********************************************************************************************************************** +* +* The function creates the platform sessions, configured in "NSM__asDefaultSessions". +* +**********************************************************************************************************************/ +static void NSM__vCreatePlatformSessions(void) +{ + NsmSession_s *pNewDefaultSession = NULL; + guint u32DefaultSessionIdx = 0; + NsmSeat_e enSeatIdx = NsmSeat_NotSet; + + /* Configure the default sessions, which are always available */ + for(u32DefaultSessionIdx = 0; + u32DefaultSessionIdx < sizeof(NSM__asDefaultSessions)/sizeof(gchar*); + u32DefaultSessionIdx++) + { + /* Create a session for every session name and seat */ + for(enSeatIdx = NsmSeat_NotSet + 1; enSeatIdx < NsmSeat_Last; enSeatIdx++) + { + pNewDefaultSession = g_new0(NsmSession_s, 1); + g_strlcpy((gchar*) pNewDefaultSession->sName, NSM__asDefaultSessions[u32DefaultSessionIdx], sizeof(pNewDefaultSession->sName)); + g_strlcpy((gchar*) pNewDefaultSession->sOwner, NSM_DEFAULT_SESSION_OWNER, sizeof(pNewDefaultSession->sOwner)); + pNewDefaultSession->enSeat = enSeatIdx; + pNewDefaultSession->enState = NsmSessionState_Inactive; + + NSM__pSessions = g_slist_append(NSM__pSessions, pNewDefaultSession); + } + } +} + + +/********************************************************************************************************************** +* +* The function creates the mutexes used in the NSM. +* +**********************************************************************************************************************/ +static void NSM__vCreateMutexes(void) +{ + /* Initialize the local mutexes */ + NSM__pNodeStateMutex = g_mutex_new(); + NSM__pApplicationModeMutex = g_mutex_new(); + NSM__pSessionMutex = g_mutex_new(); +} + + +/********************************************************************************************************************** +* +* The function deletes the mutexes used in the NSM. +* +**********************************************************************************************************************/ +static void NSM__vDeleteMutexes(void) +{ + /* Delete the local mutexes */ + g_mutex_free(NSM__pNodeStateMutex); + g_mutex_free(NSM__pApplicationModeMutex); + g_mutex_free(NSM__pSessionMutex); +} + + +/********************************************************************************************************************** +* +* The function is called to trace a syslog message for a shutdown client. +* +* @param sBus: Bus name of the shutdown client. +* @param sObj: Object name of the lifecycle client. +* @param u32Reason: Shutdown reason send to the client. +* @param sInOut: "enter" or "leave" (including failure reason) +* @param enErrorStatus: Error value +* +**********************************************************************************************************************/ +static void NSM__vLtProf(gchar *sBus, gchar *sObj, guint32 u32Reason, gchar *sInOut, NsmErrorStatus_e enErrorStatus) +{ + gchar pszLtprof[128] = "LTPROF: bus:%s obj:%s (0x%08X:%d) "; + guint32 dwLength = 128; + + g_strlcat(pszLtprof, sInOut, dwLength); + + if(u32Reason != 0) + { + if(u32Reason == NSM_SHUTDOWNTYPE_RUNUP) + { + g_strlcat(pszLtprof, "runup", dwLength); + } + else + { + g_strlcat(pszLtprof, "shutdown", dwLength); + } + } + + syslog(LOG_NOTICE, (char *)pszLtprof, sBus, sObj, u32Reason, enErrorStatus); +} + + +/********************************************************************************************************************** +* +* The function is used to initialize syslog +* +**********************************************************************************************************************/ +static void NSM__vSyslogOpen(void) +{ + openlog("NSM", LOG_PID, LOG_USER); +} + + +/********************************************************************************************************************** +* +* The function is used to deinitialize syslog +* +**********************************************************************************************************************/ +static void NSM__vSyslogClose(void) +{ + closelog(); +} + + +/********************************************************************************************************************** +* +* Interfaces. Exported functions. See Header for detailed description. +* +**********************************************************************************************************************/ + + +/* The function is called by the NodeStateMachine to set a "property" of the NSM. */ +NsmErrorStatus_e NsmSetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen) +{ + /* Function local variables */ + NsmErrorStatus_e enRetVal = NsmErrorStatus_NotSet; /* Return value */ + + /* Check which data the NSMC wants to set */ + switch(enData) + { + /* NSMC wants to set the NodeState */ + case NsmDataType_NodeState: + enRetVal = (u32DataLen == sizeof(NsmNodeState_e)) + ? NSM__enSetNodeState((NsmNodeState_e) *pData, TRUE, FALSE) + : NsmErrorStatus_Parameter; + break; + + /* NSMC wants to set the AppMode */ + case NsmDataType_AppMode: + enRetVal = (u32DataLen == sizeof(NsmApplicationMode_e)) + ? NSM__enSetApplicationMode((NsmApplicationMode_e) *pData, TRUE, FALSE) + : NsmErrorStatus_Parameter; + break; + + /* NSMC wants to set the BootMode */ + case NsmDataType_BootMode: + enRetVal = (u32DataLen == sizeof(gint)) + ? NSM__enSetBootMode((gint) *pData, FALSE) + : NsmErrorStatus_Parameter; + break; + + /* NSMC wants to set the ShutdownReason */ + case NsmDataType_ShutdownReason: + enRetVal = (u32DataLen == sizeof(NsmShutdownReason_e)) + ? NSM__enSetShutdownReason((NsmShutdownReason_e) *pData, FALSE) + : NsmErrorStatus_Parameter; + break; + + /* NSMC wants to set a SessionState */ + case NsmDataType_SessionState: + enRetVal = (u32DataLen == sizeof(NsmSession_s)) + ? NSM__enSetSessionState((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: + default: + enRetVal = NsmErrorStatus_Parameter; + break; + } + + return enRetVal; +} + + +/* The function is called by the NodeStateMachine to get a "property" of the NSM. */ +int NsmGetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen) +{ + /* Function local variables */ + int i32RetVal = -1; /* Return value. Positive: Amount of written bytes. + Negative: An error occurred. */ + + /* Check which data the NSMC wants to get */ + switch(enData) + { + /* NSMC wants to get the NodeState */ + case NsmDataType_NodeState: + if(u32DataLen == sizeof(NsmNodeState_e)) + { + if(NSM__enGetNodeState((NsmNodeState_e*) pData) == NsmErrorStatus_Ok) + { + i32RetVal = sizeof(NsmNodeState_e); + } + } + break; + + /* NSMC wants to get the ApplicationMode */ + case NsmDataType_AppMode: + if(u32DataLen == sizeof(NsmApplicationMode_e)) + { + if(NSM__enGetApplicationMode((NsmApplicationMode_e*) pData) == NsmErrorStatus_Ok) + { + i32RetVal = sizeof(NsmApplicationMode_e); + } + } + break; + + /* NSMC wants to get the BootMode */ + case NsmDataType_BootMode: + if(u32DataLen == sizeof(gint)) + { + if(NSMA_boGetBootMode((gint*) pData) == TRUE) + { + i32RetVal = sizeof(gint); + } + } + break; + + /* NSMC wants to get the RunningReason */ + case NsmDataType_RunningReason: + if(u32DataLen == sizeof(NsmRunningReason_e)) + { + if(NSMA_boGetRunningReason((NsmRunningReason_e*) pData) == TRUE) + { + i32RetVal = sizeof(NsmRunningReason_e); + } + } + break; + + /* NSMC wants to get the ShutdownReason */ + case NsmDataType_ShutdownReason: + if(u32DataLen == sizeof(NsmShutdownReason_e)) + { + if(NSMA_boGetShutdownReason((NsmShutdownReason_e*) pData) == TRUE) + { + i32RetVal = sizeof(NsmShutdownReason_e); + } + } + break; + + /* NSMC wants to get the RestartReason */ + case NsmDataType_RestartReason: + if(u32DataLen == sizeof(NsmRestartReason_e)) + { + if(NSMA_boGetRestartReason((NsmRestartReason_e*) pData) == TRUE) + { + i32RetVal = sizeof(NsmRestartReason_e); + } + } + break; + + /* NSMC wants to get the SessionState */ + case NsmDataType_SessionState: + if(u32DataLen == sizeof(NsmSession_s)) + { + if(NSM__enGetSessionState((NsmSession_s*) pData) == NsmErrorStatus_Ok) + { + i32RetVal = sizeof(NsmSession_s); + } + } + break; + + /* Error: The type of the data NSMC is trying to set is unknown. */ + default: + i32RetVal = -1; + break; + } + + return i32RetVal; +} + + +unsigned int NsmGetInterfaceVersion(void) +{ + return NSM_INTERFACE_VERSION; +} + + +/* The main function of the NodeStateManager */ +int main(void) +{ + gboolean boEndByUser = FALSE; + + /* Initialize glib for using "g" types */ + g_type_init(); + + /* Register NSM for DLT */ + DLT_REGISTER_APP("NSM", "Node State Manager"); + DLT_REGISTER_CONTEXT(NsmContext, "005", "Context for the NSM"); + DLT_ENABLE_LOCAL_PRINT(); + + /* Initialize syslog */ + NSM__vSyslogOpen(); + + /* Print first msg. to show that NSM is going to start */ + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: NodeStateManager started.")); + + /* Currently no other resources accessing the NSM. Prepare it now! */ + NSM__vInitializeVariables(); /* Initialize file local variables*/ + NSM__vCreatePlatformSessions(); /* Create platform sessions */ + NSM__vCreateMutexes(); /* Create mutexes */ + + /* Initialize the NSMA before the NSMC, because the NSMC can access properties */ + if(NSMA_boInit(&NSM__stObjectCallBacks) == TRUE) + { + /* Set the properties to initial values */ + (void) NSMA_boSetBootMode(0); + (void) NSMA_boSetRestartReason(NsmRestartReason_NotSet); + (void) NSMA_boSetShutdownReason(NsmShutdownReason_NotSet); + (void) NSMA_boSetRunningReason(NsmRunningReason_WakeupCan); + + /* Initialize/start the NSMC */ + if(NsmcInit() == 0x01) + { + /* The event loop is only canceled if the Node is completely shut down or there is an internal error. */ + boEndByUser = NSMA_boWaitForEvents(); + + if(boEndByUser == TRUE) + { + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Successfully canceled event loop. "), + DLT_STRING("Shutting down NodeStateManager." )); + } + else + { + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: Error in event loop. " ), + DLT_STRING("Shutting down NodeStateManager.")); + } + + /* The event loop returned. Clean up the NSMA. */ + (void) NSMA_boDeInit(); + } + else + { + /* Error: Failed to initialize the NSMC. Clean up NSMA, because it is not needed anymore. */ + (void) NSMA_boDeInit(); + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Error. Failed to initialize the NSMC.")); + } + } + else + { + /* Error: Failed to initialize the NSMA. */ + DLT_LOG(NsmContext, DLT_LOG_ERROR, DLT_STRING("NSM: Error. Failed to initialize the NSMA.")); + } + + /* Free the mutexes */ + NSM__vDeleteMutexes(); + + /* Remove data from all lists */ + g_slist_free_full(NSM__pSessions, &NSM__vFreeSessionObject); + g_slist_free_full(NSM__pFailedApplications, &NSM__vFreeFailedApplicationObject); + g_list_free_full (NSM__pLifecycleClients, &NSM__vFreeLifecycleClientObject); + + DLT_LOG(NsmContext, DLT_LOG_INFO, DLT_STRING("NSM: NodeStateManager stopped.")); + + /* Deinit syslog */ + NSM__vSyslogClose(); + + /* Unregister NSM from DLT */ + DLT_UNREGISTER_CONTEXT(NsmContext); + DLT_UNREGISTER_APP(); + + return 0; +} diff --git a/NodeStateManager/NodeStateManager.h b/NodeStateManager/NodeStateManager.h new file mode 100644 index 0000000..61b9995 --- /dev/null +++ b/NodeStateManager/NodeStateManager.h @@ -0,0 +1,129 @@ +#ifndef NODESTATEMANAGER_H +#define NODESTATEMANAGER_H + +/********************************************************************************************************************** +* +* Copyright (C) 2012 Continental Automotive Systems, Inc. +* +* Author: Jean-Pierre.Bogler@continental-corporation.com +* +* Interface between NodeStateManager and other components in the same process +* +* The file defines the interfaces and data types, which components in the same process or on the D-Bus +* can use to communicate to the NodeStateManager (NSM). Please note that there are further interfaces +* defined in XML to access the NSM via D-Bus. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* 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 +* 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. +* +**********************************************************************************************************************/ + +/** \ingroup SSW_LCS */ +/** \defgroup SSW_NSM_TEMPLATE Node State Manager + * \{ + */ +/** \defgroup SSW_NSM_INTERFACE API document + * \{ + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************************************************************** +* +* HEADER FILE INCLUDES +* +**********************************************************************************************************************/ + +#include "NodeStateTypes.h" + +/********************************************************************************************************************** +* +* CONSTANTS +* +**********************************************************************************************************************/ + +/** + * Module version, use SswVersion to interpret the value. + * The lower significant byte is equal 0 for released version only + */ + +#define NSM_INTERFACE_VERSION 0x01020000U + +/********************************************************************************************************************** +* +* TYPE +* +**********************************************************************************************************************/ + +/* There are no types defined here */ + +/********************************************************************************************************************** +* +* GLOBAL VARIABLES +* +**********************************************************************************************************************/ + +/* There are no exported global variables */ + + +/********************************************************************************************************************** +* +* FUNCTION PROTOTYPE +* +**********************************************************************************************************************/ + +/** \brief Set data (property) of the NodeStateManager. +\param[in] enData Type of the data to set (see ::NsmDataType_e). +\param[in] pData Pointer to the memory location containing the data. +\param[in] u32DataLen Length of the data that should be set (in byte). +\retval see ::NsmErrorStatus_e + +This is a generic interface that can be used by the NSMc to write a specific data item that from the NSM. */ +NsmErrorStatus_e NsmSetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen); + + +/** \brief Get data (property) of the NodeStateManager. +\param[in] enData Type of the data to get (see ::NsmDataType_e). +\param[out] pData Pointer to the memory location where the data should be stored. +\param[in] u32DataLen Length of the data that should be stored (in byte). +\retval A positive value indicates the number of bytes that have been written to the out buffer pData. + A negative value indicates an error. + +This is a generic interface that can be used by the NSMc to read a specific data item that from the NSM. */ +int NsmGetData(NsmDataType_e enData, unsigned char *pData, unsigned int u32DataLen); + + +/** \brief Get version of the interface +\retval Version of the interface as defined in ::SswVersion_t + +This function asks the lifecycle to perform a restart of the main controller. */ +unsigned int NsmGetInterfaceVersion(void); + + +/********************************************************************************************************************** +* +* MACROS +* +**********************************************************************************************************************/ + +/* There are no macros defined */ + + +#ifdef __cplusplus +} +#endif +/** \} */ /* End of SSW_NSM_INTERFACE */ +/** \} */ /* End of SSW_NSM_TEMPLATE */ +#endif /* NSM_NODESTATEMANAGER_H */ diff --git a/NodeStateManager/NodeStateTypes.h b/NodeStateManager/NodeStateTypes.h new file mode 100644 index 0000000..023dfa9 --- /dev/null +++ b/NodeStateManager/NodeStateTypes.h @@ -0,0 +1,252 @@ +#ifndef NODESTATETYPES_H +#define NODESTATETYPES_H + +/********************************************************************************************************************** +* +* Copyright (C) 2012 Continental Automotive Systems, Inc. +* +* Author: Jean-Pierre.Bogler@continental-corporation.com +* +* Type and constant definitions to communicate with the NSM. +* +* The file defines types and constants to be able to communicate with the NSM. +* +* This Source Code Form is subject to the terms of the Mozilla Public +* 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 +* 2012.09.27 uidu5846 1.0.0.0 CSP_WZ#1194: Introduced 'NodeStateTypes.h' to avoid circle includes +* 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. +* +**********************************************************************************************************************/ + +/** \ingroup SSW_LCS */ +/** \defgroup SSW_NSM_TEMPLATE Node State Manager + * \{ + */ +/** \defgroup SSW_NSM_INTERFACE API document + * \{ + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************************************************************** +* +* CONSTANTS +* +**********************************************************************************************************************/ + +/* Definitions of D-Bus names and addresses */ +#define NSM_BUS_TYPE 1 /**< Defines bus type according to GBusType */ +#define NSM_BUS_NAME "org.genivi.NodeStateManager" /**< The bus name of the NSM */ +#define NSM_LIFECYCLE_OBJECT "/org/genivi/NodeStateManager/LifecycleControl" /**< Address of the lifecycle object */ +#define NSM_CONSUMER_OBJECT "/org/genivi/NodeStateManager/Consumer" /**< Address of the consumer object */ + +/* Defines for session handling */ +#define NSM_DEFAULT_SESSION_OWNER "NodeStateManager" /**< "Owner" of the default sessions */ + +/* Defines for internal settings like max. string lenghts */ +#define NSM_MAX_SESSION_NAME_LENGTH 256 /**< Max. number of chars a session name can have */ +#define NSM_MAX_SESSION_OWNER_LENGTH 256 /**< Max. number of chars for name of session owner */ + +/* + * Defines for shutdown handling as bit masks. Used to register for multiple shutdown types and as parameter to + * inform clients about the shutdown type via the LifecycleConsumer interface. + */ +#define NSM_SHUTDOWNTYPE_NOT 0x00000000U /**< Client not registered for any shutdown */ +#define NSM_SHUTDOWNTYPE_NORMAL 0x00000001U /**< Client registered for normal shutdown */ +#define NSM_SHUTDOWNTYPE_FAST 0x00000002U /**< Client registered for fast shutdown */ +#define NSM_SHUTDOWNTYPE_RUNUP 0x80000000U /**< The shutdown type "run up" can not be used for + registration. Clients which are registered and + have been shut down, will automatically be + informed about the "run up", when the shut down + is canceled. */ + +/********************************************************************************************************************** +* +* TYPE +* +**********************************************************************************************************************/ + +/** + * The enumeration defines the different types of data that can be exchanged between the NodeStateManager (NSM) + * and the NodeStateMachine (NSMC). Based on this value, the setter and getter functions of the NSM and NSMC will + * interpret data behind the passed byte pointer. + */ +typedef enum _NsmDataType_e +{ + NsmDataType_AppMode, /**< An ApplicationMode should be set or get */ + NsmDataType_NodeState, /**< A NodeState should be set or get */ + NsmDataType_RestartReason, /**< A RestartReason should be set or get */ + 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_e; + + +/** + * The enumeration defines the different wake up reasons. + */ +typedef enum _NsmErrorStatus_e +{ + NsmErrorStatus_NotSet, /**< Initial value when error type is not set */ + NsmErrorStatus_Ok, /**< Value when no error occurred */ + NsmErrorStatus_Error, /**< A general, non-specific error occurred */ + NsmErrorStatus_Dbus, /**< Error in D-Bus communication */ + NsmErrorStatus_Internal, /**< Internal error (memory alloc. failed, etc.) */ + NsmErrorStatus_Parameter, /**< A passed parameter was incorrect */ + NsmErrorStatus_WrongSession, /**< The requested session is unknown. */ + NsmErrorStatus_ResponsePending, /**< Command accepted, return value delivered asynch. */ + NsmErrorStatus_Last /**< Last error value to identify valid errors */ +} NsmErrorStatus_e; + + +/** + * Possible application modes of the node. + */ +typedef enum _NsmApplicationMode_e +{ + NsmApplicationMode_NotSet, /**< Initial state */ + NsmApplicationMode_Parking, /**< Parking mode */ + NsmApplicationMode_Factory, /**< Factory mode */ + NsmApplicationMode_Transport, /**< Transport mode */ + NsmApplicationMode_Normal, /**< Normal mode */ + NsmApplicationMode_Swl, /**< Software loading mode */ + NsmApplicationMode_Last /**< Last value to identify valid values */ +}NsmApplicationMode_e; + + +/** + * The enumeration defines the different restart reasons. + */ +typedef enum _NsmRestartReason_e +{ + NsmRestartReason_NotSet, /**< Initial value when reset reason is not set */ + NsmRestartReason_ApplicationFailure, /**< Reset was requested by System Health Mon. */ + NsmRestartReason_Diagnosis, /**< Reset was requested by diagnosis */ + NsmRestartReason_Swl, /**< Reset was requested by the SWL application */ + NsmRestartReason_User, /**< Reset was requested by an user application */ + NsmRestartReason_Last /**< Last value to identify valid reset reasons */ +} NsmRestartReason_e; + + +/** + * Session can be enabled seat depended. + */ +typedef enum _NsmSeat_e +{ + NsmSeat_NotSet, /**< Initial state */ + NsmSeat_Driver, /**< Driver seat */ + NsmSeat_CoDriver, /**< CoDriver seat */ + NsmSeat_Rear1, /**< Rear 1 */ + NsmSeat_Rear2, /**< Rear 2 */ + NsmSeat_Rear3, /**< Rear 3 */ + NsmSeat_Last /**< Last valid state */ +}NsmSeat_e; + + +/** + * The enumeration defines the different wake up reasons. + */ +typedef enum _NsmSessionState_e +{ + NsmSessionState_Unregistered, /**< Initial state, equals "not set" */ + NsmSessionState_Inactive, /**< Session is inactive */ + NsmSessionState_Active /**< Session is active */ +} NsmSessionState_e; + +/** + * The enumeration defines the different shutdown reasons. + */ +typedef enum _NsmShutdownReason_e +{ + NsmShutdownReason_NotSet, /**< Initial value when ShutdownReason not set */ + NsmShutdownReason_Normal, /**< A normal shutdown has been performed */ + NsmShutdownReason_SupplyBad, /**< Shutdown because of bad supply */ + NsmShutdownReason_SupplyPoor, /**< Shutdown because of poor supply */ + NsmShutdownReason_ThermalBad, /**< Shutdown because of bad thermal state */ + NsmShutdownReason_ThermalPoor, /**< Shutdown because of poor thermal state */ + NsmShutdownReason_SwlNotActive, /**< Shutdown after software loading */ + NsmShutdownReason_Last /**< Last value. Identify valid ShutdownReasons */ +} NsmShutdownReason_e; + +/** + * The enumeration defines the different start or wake up reasons. + */ +typedef enum _NsmRunningReason_e +{ + NsmRunningReason_NotSet, /**< Initial value when reason is not set. */ + NsmRunningReason_WakeupCan, /**< Wake up because of CAN activity */ + NsmRunningReason_WakeupMediaEject, /**< Wake up because of 'Eject' button */ + NsmRunningReason_WakeupMediaInsertion, /**< Wake up because of media insertion */ + NsmRunningReason_WakeupHevac, /**< Wake up because of user uses the HEVAC unit in the car. + Even if the HEVAC actually causes activity on the CAN bus a + different wakeup reason is required as it could result in a + different level of functionality being started */ + NsmRunningReason_WakeupPhone, /**< Wake up because of a phone call being received. + Even if this is passed as a CAN event a different wakeup reason + is required as it could result in a different level of + functionality being started */ + NsmRunningReason_WakeupPowerOnButton, /**< Startup because user presses the "Power ON" button in the car. + Even if this is passed as a CAN event a different wakeup reason + is required as it could result in a different level of + functionality being started */ + NsmRunningReason_StartupFstp, /**< System was started due to a first switch to power */ + NsmRunningReason_StartupSwitchToPower, /**< System was switched to power */ + NsmRunningReason_RestartSwRequest, /**< System was restarted due to an internal SW Request + (i.e. SWL or Diagnosis) */ + NsmRunningReason_RestartInternalHealth, /**< System was restarted due to an internal health problem */ + NsmRunningReason_RestartExternalHealth, /**< System was restarted due to an external health problem + (i.e. external wdog believed node was in failure) */ + NsmRunningReason_RestartUnexpected, /**< System was restarted due to an unexpected kernel restart. + This will be the default catch when no other reason is known */ + NsmRunningReason_RestartUser, /**< Target was reset due to user action (i.e user 3 finger press) */ + NsmRunningReason_PlatformEnd = 0x7F, /**< Last value (127) to identify where the platform defines end + (product will start from here on) */ + NsmRunningReason_ProductOffset = NsmRunningReason_PlatformEnd + 1 /**< product will start from here with index 0 */ +} NsmRunningReason_e; + + +/** + * The enumeration defines the different node states + */ +typedef enum _NsmNodeState_e +{ + NsmNodeState_NotSet, /**< Initial state when node state is not set */ + NsmNodeState_StartUp, /**< Basic system is starting up */ + NsmNodeState_BaseRunning, /**< Basic system components have been started */ + NsmNodeState_LucRunning, /**< All 'Last user context' components have been started */ + NsmNodeState_FullyRunning, /**< All 'foreground' components have been started */ + NsmNodeState_FullyOperational, /**< All components have been started */ + NsmNodeState_ShuttingDown, /**< The system is shutting down */ + NsmNodeState_ShutdownDelay, /**< Shutdown request active. System will shutdown soon */ + NsmNodeState_FastShutdown, /**< Fast shutdown active */ + NsmNodeState_DegradedPower, /**< Node is in degraded power state */ + NsmNodeState_Shutdown, /**< Node is completely shut down */ + NsmNodeState_Last /**< Last valid entry to identify valid node states */ +} NsmNodeState_e; + + +/** The type defines the structure for a session. */ +typedef struct _NsmSession_s +{ + char sName[NSM_MAX_SESSION_NAME_LENGTH]; /**< Name of the session */ + char sOwner[NSM_MAX_SESSION_OWNER_LENGTH]; /**< Owner of the session */ + NsmSeat_e enSeat; /**< Seat of the session */ + NsmSessionState_e enState; /**< State of the session */ +} NsmSession_s, *pNsmSession_s; + + +#ifdef __cplusplus +} +#endif +/** \} */ /* End of SSW_NSM_INTERFACE */ +/** \} */ /* End of SSW_NSM_TEMPLATE */ +#endif /* NODESTATETYPES_H */ diff --git a/NodeStateManager/config/nodestatemanager-daemon.service.in b/NodeStateManager/config/nodestatemanager-daemon.service.in new file mode 100644 index 0000000..03177bb --- /dev/null +++ b/NodeStateManager/config/nodestatemanager-daemon.service.in @@ -0,0 +1,15 @@ +# This file is for starting the nodestatemanager-daemon as a service with systemd + +[Unit] +Description=NodeStateManager to provide system states, session and shutdown handling +Wants=dbus.service dlt-daemon.service +After=dbus.service dlt-daemon.service + +# Start up very early, because it doesn't need anything to run prior to it: +DefaultDependencies=no + +[Service] +ExecStart=/usr/bin/NodeStateManager + +[Install] +WantedBy=basic.target diff --git a/NodeStateManager/config/org.genivi.NodeStateManager.LifeCycleControl.service.in b/NodeStateManager/config/org.genivi.NodeStateManager.LifeCycleControl.service.in new file mode 100644 index 0000000..f6e3d8a --- /dev/null +++ b/NodeStateManager/config/org.genivi.NodeStateManager.LifeCycleControl.service.in @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.genivi.NodeStateManager +SystemdService = nodestatemanager-daemon.service +Exec=/bin/false diff --git a/NodeStateManager/config/org.genivi.NodeStateManager.conf b/NodeStateManager/config/org.genivi.NodeStateManager.conf new file mode 100644 index 0000000..74b188e --- /dev/null +++ b/NodeStateManager/config/org.genivi.NodeStateManager.conf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/README b/README new file mode 100644 index 0000000..c575858 --- /dev/null +++ b/README @@ -0,0 +1,32 @@ +GENIVI NodeStateManager (NSM) README +===================================== + +This is the official source of the GENIVI NodeStateManager. At present, all +relevant documentation for this project is available in the GENIVI wiki on: + +https://collab.genivi.org/wiki/display/genivi/SysInfraEGLifecycleNSMData + + +License +------- + +For licensing information see the COPYING file, +distributed along with this project. + + +Build Dependencies and Instructions +----------------------------------- + +The NodeStateManager needs glib >= 2.30.0 to be compiled. +In addition, the NodeStateManager(NSM) has dependencies +to the NodeStateMachine (NSMC) and NodeStateAccess (NSMA). + +The NSMC and NSMA are delivered within this package as +stubs. To understand the tasks of these two components, +please see their interface headers. + +Please note: Due to legal restrictions the NSMA had to be +introduced. It is responsible for binding the NSM to the +IPC. In most cases probably D-Bus is used for the IPC and +the xml files in the "model" folder of the NSM describe the +IPC interfaces offered by the NSM. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..c34b34d --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh -e +autoreconf --install --symlink +./configure $@ diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..ed014e9 --- /dev/null +++ b/configure.ac @@ -0,0 +1,87 @@ +####################################################################################################################### +# +# Copyright (C) 2012 Continental Automotive Systems, Inc. +# +# Author: Jean-Pierre.Bogler@continental-corporation.com +# +# Configure template for the NodeStateManager +# +# Process this file with autoconf to produce a configure script. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# 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/. +# +####################################################################################################################### + +dnl *************************** +dnl *** Initialize autoconf *** +dnl *************************** +AC_INIT([node-state-manager], [1.2.0.0]) +AC_COPYRIGHT([Copyright (c) 2012 Continental Automotive GmbH]) +AC_PREREQ([2.50]) + +dnl *************************** +dnl *** Initialize automake *** +dnl *************************** +AM_INIT_AUTOMAKE() +AC_CONFIG_MACRO_DIR([m4]) +AC_SUBST([ACLOCAL_AMFLAGS], ["$ACLOCAL_FLAGS -I m4"]) + +dnl ******************************** +dnl *** Check for basic programs *** +dnl ******************************** +AC_PROG_CC() +AM_PROG_CC_C_O() +AC_PROG_INSTALL() + +dnl *************************************** +dnl *** Initialize lib tool *** +dnl *************************************** +AC_DISABLE_STATIC() +AC_PROG_LIBTOOL() + +dnl *************************************** +dnl *** Check for standard header files *** +dnl *************************************** +AC_CHECK_HEADERS([string.h]) + +dnl ************************************ +dnl *** Check for standard functions *** +dnl ************************************ +AC_CHECK_FUNCS([memcpy]) + +dnl *********************************** +dnl *** Check for required packages *** +dnl *********************************** +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]) + +dnl ************************************* +dnl *** Define extra paths *** +dnl ************************************* +AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), + [], + [with_systemdsystemunitdir=$(pkg-config --silence-errors --variable=systemdsystemunitdir systemd)]) +AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) + +AC_ARG_WITH([dbussystemunitdir], + AS_HELP_STRING([--with-dbussystemunitdir=DIR], [Directory for D-Bus system service files]), + [], + [with_dbussystemunitdir=$(pkg-config --silence-errors --variable=system_bus_services_dir dbus-1)]) +AC_SUBST([dbussystemunitdir], [$with_dbussystemunitdir]) + +AC_ARG_WITH([dbuspolicydir], + AS_HELP_STRING([--with-dbuspolicydirdir=DIR], [Directory for D-Bus system policy files]), + [], + [with_dbuspolicydir=$(pkg-config --silence-errors --variable=sysconfdir dbus-1)/dbus-1/system.d]) +AC_SUBST([dbuspolicydir], [$with_dbuspolicydir]) + +dnl ************************************ +dnl *** Define configure output *** +dnl ************************************ +AC_OUTPUT(Makefile NodeStateManager/Makefile NodeStateAccessStub/Makefile NodeStateMachineStub/Makefile NodeStateManager/config/nodestatemanager-daemon.service NodeStateManager/config/org.genivi.NodeStateManager.LifeCycleControl.service) -- cgit v1.2.1