/********************************************************************************************************************** * * 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). * The architecture requires that the NodeStateManager (NSM) is independent from the D-Bus binding and code generated by * "gdbus-codegen". Therefore, the D-Bus communication and generated D-Bus objects are handled inside of this library. * The library offers the NSM an interface to use objects generated via gdbus-codgen. * * 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 * 24.01.2013 Jean-Pierre Bogler CSP_WZ#1194: Fixed bug. LifecycleRequestComnplete did not send dbus response. * **********************************************************************************************************************/ /********************************************************************************************************************** * * 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 */ #include "string.h" /* memcpy, memset, etc. */ #include "NodeStateConsumer.h" /* generated NodeStateConsumer object */ #include "NodeStateLifecycleControl.h" /* generated LifecycleControl object */ #include "NodeStateLifecycleConsumer.h" /* generated LifecycleConsumer object */ /********************************************************************************************************************** * * Local variables * **********************************************************************************************************************/ /* Variables to handle main loop and bus connection */ static GMainLoop *NSMA__pMainLoop = NULL; static GDBusConnection *NSMA__pBusConnection = NULL; static gboolean NSMA__boLoopEndByUser = FALSE; static guint NSMA__u32ConnectionId = 0; static gboolean NSMA__boInitialized = FALSE; /* Variables to handle life cycle client calls */ static guint NSMA__u32TimerId = 0; static NodeStateLifeCycleConsumer *NSMA__pCurrentLcConsumer = NULL; /* Variables for D-Bus objects */ static NodeStateConsumer *NSMA__pNodeStateConsumerObj = NULL; static NodeStateLifecycleControl *NSMA__pLifecycleControlObj = NULL; /* Structure with callback functions to the NSM */ static NSMA_tstObjectCallbacks NSMA__stObjectCallbacks = {0}; /********************************************************************************************************************** * * Prototypes for file local functions (see implementation for description) * **********************************************************************************************************************/ /* Internal D-Bus callbacks */ static gboolean NSMA__boOnHandleSetBootMode (NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32BootMode, gpointer pUserData); static gboolean NSMA__boOnHandleSetNodeState (NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32NodeStateId, gpointer pUserData); static gboolean NSMA__boOnHandleSetApplicationMode (NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32ApplicationModeId, gpointer pUserData); static gboolean NSMA__boOnHandleRequestNodeRestart (NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32RestartReason, const guint i32RestartType, gpointer pUserData); static gboolean NSMA__boOnHandleCheckLucRequired (NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, gpointer pUserData); static gboolean NSMA__boOnHandleRegisterSession (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gchar *sSessionOwner, const gint i32SeatId, const gint i32SessionState, gpointer pUserData); static gboolean NSMA__boOnHandleUnRegisterSession (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gchar *sSessionOwner, const gint i32SeatId, gpointer pUserData); static gboolean NSMA__boOnHandleRegisterLifecycleClient (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar* sBusName, const gchar* sObjName, const guint u32ShutdownMode, const guint u32TimeoutMs, gpointer pUserData); static gboolean NSMA__boOnHandleUnRegisterLifecycleClient(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar* sBusName, const gchar* sObjName, const guint u32ShutdownMode, gpointer pUserData); static gboolean NSMA__boOnHandleLifecycleRequestComplete (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const guint u32RequestId, const gint i32Status, gpointer pUserData); static gboolean NSMA__boOnHandleGetApplicationMode (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData); static gboolean NSMA__boOnHandleGetSessionState (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gint i32SeatId, gpointer pUserData); static gboolean NSMA__boOnHandleSetSessionState (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gchar *sSessionOwner, const gint i32SeatId, const gint i32SessionState, gpointer pUserData); static gboolean NSMA__boOnHandleGetNodeState (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData); static gboolean NSMA__boOnHandleSetAppHealthStatus (NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gchar *sAppName, const gboolean boAppState, gpointer pUserData); static gboolean NSMA__boOnHandleGetAppHealthCount (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData); static gboolean NSMA__boOnHandleGetInterfaceVersion (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData); /* Internal bus connection callbacks */ static void NSMA__vOnBusAcquired (GDBusConnection *pConnection, const gchar* sName, gpointer pUserData); static void NSMA__vOnNameAcquired(GDBusConnection *pConnection, const gchar* sName, gpointer pUserData); static void NSMA__vOnNameLost (GDBusConnection *pConnection, const gchar* sName, gpointer pUserData); /* Internal callback for async. life cycle client returns */ static void NSMA__vOnLifecycleRequestFinish(GObject *pSrcObject, GAsyncResult *pRes, gpointer pUserData); /********************************************************************************************************************** * * Local (static) functions * **********************************************************************************************************************/ /********************************************************************************************************************** * * The function is called from the g_main_loop, when the "boot mode" should be set. * * @param pLifecycleControl: Pointer to a LifecycleControl object * @param pInvocation: Pointer to method invocation object * @param i32BootMode: New boot mode * @param pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleSetBootMode(NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32BootMode, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfSetBootModeCb(i32BootMode); node_state_lifecycle_control_complete_set_boot_mode(pLifecycleControl, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when the "node state" should be set. * * @param pLifecycleControl: Pointer to a LifecycleControl object * @param pInvocation: Pointer to method invocation object * @param i32NodeStateId: New node state * @param pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleSetNodeState(NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32NodeStateId, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfSetNodeStateCb((NsmNodeState_e) i32NodeStateId); node_state_lifecycle_control_complete_set_node_state(pLifecycleControl, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when the "application mode" should be set. * * @param pLifecycleControl: Pointer to a LifecycleControl object * @param pInvocation: Pointer to method invocation object * @param i32ApplicationModeId: New application mode * @param pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleSetApplicationMode(NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32ApplicationModeId, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfSetAppModeCb((NsmApplicationMode_e) i32ApplicationModeId); node_state_lifecycle_control_complete_set_application_mode(pLifecycleControl, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when the node should be reset. * * @param pLifecycleControl: Pointer to a LifecycleControl object * @param pInvocation: Pointer to method invocation object * @param i32RestartReason: Restart reason * @param i32RestartType: Restart type * @param pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleRequestNodeRestart(NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gint i32RestartReason, const guint u32RestartType, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfRequestNodeRestartCb((NsmRestartReason_e) i32RestartReason, u32RestartType); node_state_lifecycle_control_complete_request_node_restart(pLifecycleControl, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when a check for LUC is required. * * @param pLifecycleControl: Pointer to a LifecycleControl object * @param pInvocation: Pointer to method invocation object * @param pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleCheckLucRequired(NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, gpointer pUserData) { gboolean boLucRequired = FALSE; boLucRequired = NSMA__stObjectCallbacks.pfCheckLucRequiredCb(); node_state_lifecycle_control_complete_check_luc_required(pLifecycleControl, pInvocation, boLucRequired); return TRUE; } /********************************************************************************************************************** * * The function is called when an application has become invalid or valid again. * * @param pLifecycleControl: Caller of the D-Bus interface * @param pInvocation: Pointer to the interface invocation * @param sAppName: Application which changed its state. * @param boAppState: Indicates whether the application has become invalid or valid again. * @param pUserData: Optionally user data (not used) * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleSetAppHealthStatus(NodeStateLifecycleControl *pLifecycleControl, GDBusMethodInvocation *pInvocation, const gchar *sAppName, const gboolean boAppState, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfSetAppHealthStatusCb(sAppName, boAppState); node_state_lifecycle_control_complete_set_app_health_status(pLifecycleControl, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when a new session should be registered. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to method invocation object * @param sSessionName: Name of the new session * @param i32SessionState: Initial state of the new session * @param pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleRegisterSession(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gchar *sSessionOwner, const gint i32SeatId, const gint i32SessionState, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfRegisterSessionCb(sSessionName, sSessionOwner, (NsmSeat_e) i32SeatId, (NsmSessionState_e) i32SessionState); node_state_consumer_complete_register_session(pConsumer, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when a session should be unregistered. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to method invocation object * @param sSessionName: Name of the new session * @param pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleUnRegisterSession (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gchar *sSessionOwner, const gint i32SeatId, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfUnRegisterSessionCb(sSessionName, sSessionOwner, (NsmSeat_e) i32SeatId); node_state_consumer_complete_un_register_session(pConsumer, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when a lifecycle client should be registered. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to method invocation object * @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 pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleRegisterLifecycleClient (NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sBusName, const gchar *sObjName, const guint u32ShutdownMode, const guint u32TimeoutMs, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfRegisterLifecycleClientCb(sBusName, sObjName, u32ShutdownMode, u32TimeoutMs); node_state_consumer_complete_register_shutdown_client(pConsumer, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop, when a lifecycle client should be unregistered or a shutdown * mode should be removed. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to method invocation object * @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 pUserData: Optionally user data (not used) * * @return: TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleUnRegisterLifecycleClient(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sBusName, const gchar *sObjName, const guint u32ShutdownMode, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfUnRegisterLifecycleClientCb(sBusName, sObjName, u32ShutdownMode); node_state_consumer_complete_un_register_shutdown_client(pConsumer, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop when the application mode needs to be retrieved. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to a method invocation object * @param pUserData: Pointer to optional user data (not used) * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleGetApplicationMode(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; NsmApplicationMode_e enApplicationMode = NsmApplicationMode_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfGetAppModeCb(&enApplicationMode); node_state_consumer_complete_get_application_mode(pConsumer, pInvocation, (gint) enApplicationMode, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop a session state should be retrieved. * * @param pConsumer: Caller of the D-Bus interface * @param pInvocation: Pointer to the interface invocation * @param sSessionName: Name of the session whose state just be returned * @param sSessionName: Owner of the session whose state just be returned * @param i32SeatId: Seat of the session * @param i32SessionState: New state of the session * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleGetSessionState(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gint i32SeatId, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; NsmSessionState_e enSessionState = NsmSessionState_Unregistered; enErrorStatus = NSMA__stObjectCallbacks.pfGetSessionStateCb(sSessionName, (NsmSeat_e) i32SeatId, &enSessionState); node_state_consumer_complete_get_session_state(pConsumer, pInvocation, (gint) enSessionState, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop when a session state should be set. * * @param pConsumer: Caller of the D-Bus interface * @param pInvocation: Pointer to the interface invocation * @param sSessionName: Name of the session whose state just be set * @param i32SeatId: Seat of the session * @param i32SessionState: New state of the session * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleSetSessionState(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const gchar *sSessionName, const gchar *sSessionOwner, const gint i32SeatId, const gint i32SessionState, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfSetSessionStateCb(sSessionName, sSessionOwner, (NsmSeat_e) i32SeatId, (NsmSessionState_e) i32SessionState); node_state_consumer_complete_set_session_state(pConsumer, pInvocation, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop when the NodeState needs to be retrieved. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to a method invocation object * @param pUserData: Pointer to optional user data (not used) * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleGetNodeState(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; NsmNodeState_e enNodeState = NsmNodeState_NotSet; enErrorStatus = NSMA__stObjectCallbacks.pfGetNodeStateCb(&enNodeState); node_state_consumer_complete_get_node_state(pConsumer, pInvocation, (gint) enNodeState, (gint) enErrorStatus); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop when the AppHealthCount (number of failed applications) needs to * be retrieved. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to a method invocation object * @param pUserData: Pointer to optional user data (not used) * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleGetAppHealthCount(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData) { guint u32AppHealthCount = 0; u32AppHealthCount = NSMA__stObjectCallbacks.pfGetAppHealthCountCb(); node_state_consumer_complete_get_app_health_count(pConsumer, pInvocation, u32AppHealthCount); return TRUE; } /********************************************************************************************************************** * * The function is called from the g_main_loop when the interface version needs to be retrieved. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to a method invocation object * @param pUserData: Pointer to optional user data (not used) * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleGetInterfaceVersion(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, gpointer pUserData) { guint u32InterfaceVersion = 0; u32InterfaceVersion = NSMA__stObjectCallbacks.pfGetInterfaceVersionCb(); node_state_consumer_complete_get_interface_version(pConsumer, pInvocation, u32InterfaceVersion); return TRUE; } /********************************************************************************************************************** * * The function is called when a connection to the D-Bus could be established. * * @param pConnection: Connection, which was acquired * @param sName: Bus name * @param pUserData: Optionally user data * * @return void * **********************************************************************************************************************/ static void NSMA__vOnBusAcquired(GDBusConnection *pConnection, const gchar* sName, gpointer pUserData) { /* Store the connection. Needed later, to create life cycle clients. */ NSMA__pBusConnection = pConnection; /* Register the callbacks */ (void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-set-boot-mode", G_CALLBACK(NSMA__boOnHandleSetBootMode), NULL); (void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-set-node-state", G_CALLBACK(NSMA__boOnHandleSetNodeState), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-get-node-state", G_CALLBACK(NSMA__boOnHandleGetNodeState), NULL); (void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-set-application-mode", G_CALLBACK(NSMA__boOnHandleSetApplicationMode), NULL); (void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-request-node-restart", G_CALLBACK(NSMA__boOnHandleRequestNodeRestart), NULL); (void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-check-luc-required", G_CALLBACK(NSMA__boOnHandleCheckLucRequired), NULL); (void) g_signal_connect(NSMA__pLifecycleControlObj, "handle-set-app-health-status", G_CALLBACK(NSMA__boOnHandleSetAppHealthStatus), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-register-session", G_CALLBACK(NSMA__boOnHandleRegisterSession), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-un-register-session", G_CALLBACK(NSMA__boOnHandleUnRegisterSession), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-register-shutdown-client", G_CALLBACK(NSMA__boOnHandleRegisterLifecycleClient), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-un-register-shutdown-client", G_CALLBACK(NSMA__boOnHandleUnRegisterLifecycleClient), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-get-application-mode", G_CALLBACK(NSMA__boOnHandleGetApplicationMode), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-get-session-state", G_CALLBACK(NSMA__boOnHandleGetSessionState), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-set-session-state", G_CALLBACK(NSMA__boOnHandleSetSessionState), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-get-app-health-count", G_CALLBACK(NSMA__boOnHandleGetAppHealthCount), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-get-interface-version", G_CALLBACK(NSMA__boOnHandleGetInterfaceVersion), NULL); (void) g_signal_connect(NSMA__pNodeStateConsumerObj, "handle-lifecycle-request-complete", G_CALLBACK(NSMA__boOnHandleLifecycleRequestComplete), NULL); /* Export the interfaces */ if(g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(NSMA__pNodeStateConsumerObj), NSMA__pBusConnection, NSM_CONSUMER_OBJECT, NULL) == TRUE) { if(g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(NSMA__pLifecycleControlObj), NSMA__pBusConnection, NSM_LIFECYCLE_OBJECT, NULL) != TRUE) { /* Error: The LifecycleControl interface could not be exported */ NSMA__boLoopEndByUser = FALSE; g_main_loop_quit(NSMA__pMainLoop); } } else { /* Error: The NodeStateConsumer interface could not be exported */ NSMA__boLoopEndByUser = FALSE; g_main_loop_quit(NSMA__pMainLoop); } } /********************************************************************************************************************** * * The function is called when the "bus name" could be acquired on the D-Bus. * * @param pConnection: Connection over which the bus name was acquired * @param sName: Acquired bus name * @param pUserData: Optionally user data * * @return void * **********************************************************************************************************************/ static void NSMA__vOnNameAcquired(GDBusConnection *pConnection, const gchar* sName, gpointer pUserData) { /* There is nothing to do in this function, it is only need as callback function. */ } /********************************************************************************************************************** * * The function is called if either no connection to D-Bus could be established or the bus name could not be acquired. * * @param pConnection: Connection. If it is NULL, no D-Bus connection could be established. * Otherwise the bus name was lost. * @param sName: Bus name * @param pUserData: Optionally user data * * @return void * **********************************************************************************************************************/ static void NSMA__vOnNameLost(GDBusConnection *pConnection, const gchar* sName, gpointer pUserData) { /* If this function was called, either the bus connection could not be established or the bus name could * not be obtained. In both cases, stop the main loop. */ NSMA__boLoopEndByUser = FALSE; g_main_loop_quit(NSMA__pMainLoop); } /********************************************************************************************************************** * * The function is called when the async. call to a life cycle clients "LifecycleRequest" method timed out. * * @param pUserData: Optionally user data (not used) * * @return FALSE: Tell the loop to detach and destroy the time out source. * **********************************************************************************************************************/ static gboolean NSMA__boHandleRequestTimeout(gpointer pUserData) { NSMA__pCurrentLcConsumer = NULL; NSMA__stObjectCallbacks.pfLcClientRequestFinish(NsmErrorStatus_Error); return FALSE; } /********************************************************************************************************************** * * The function is called when the async. call to a life cycle clients "LifecycleRequest" method delivered a value. * If the returned error code is not "NsmErrorStatus_ResponsePending", the error code will be forwarded to the NSM. * Otherwise, a timer will be started and the life cycle client will get another "default timeout" time, to call * the completion function "NSMA__boOnHandleLifecycleRequestComplete". * * @param pSrcObject: Source object that delivered the async. value * @param pRes: Result of the call. * @param pUserData: Optionally user data (not used). * **********************************************************************************************************************/ static void NSMA__vOnLifecycleRequestFinish(GObject *pSrcObject, GAsyncResult *pRes, gpointer pUserData) { /* Function local variables. */ NsmErrorStatus_e enErrorCode = NsmErrorStatus_NotSet; /* Error returned by lifecycle client */ guint u32Timeout = 0; /* Pass proxy object and async. result to get the return value of the lifecycle client's method and D-Bus errors. */ /* Check if a D-Bus error occurred */ if(node_state_life_cycle_consumer_call_lifecycle_request_finish(NODE_STATE_LIFE_CYCLE_CONSUMER(pSrcObject), (gint*) &enErrorCode, pRes, NULL) == TRUE) { /* The returned value could be read, check it! */ if(enErrorCode == NsmErrorStatus_ResponsePending) { /* The client returned response pending. Start timer to wait for final result. */ u32Timeout = g_dbus_proxy_get_default_timeout(G_DBUS_PROXY(pSrcObject)); NSMA__u32TimerId = g_timeout_add_full(G_PRIORITY_DEFAULT, u32Timeout, &NSMA__boHandleRequestTimeout, NULL, NULL); } else { /* The client returned a final value. Pass it to the NSM */ NSMA__pCurrentLcConsumer = NULL; NSMA__stObjectCallbacks.pfLcClientRequestFinish(enErrorCode); } } else { /* The clients return value could not be read. Pass an error to the NSM. */ NSMA__pCurrentLcConsumer = NULL; NSMA__stObjectCallbacks.pfLcClientRequestFinish(NsmErrorStatus_Dbus); } } /********************************************************************************************************************** * * The function is called from the g_main_loop when a life cycle client finished an "asynchronous" life cycle request. * * @param pConsumer: Pointer to a NodeStateConsumer object * @param pInvocation: Pointer to a method invocation object * @param u32RequestId: Request ID that has been passed to client when calling his LifecycleRequest method * @param i32Status: Status/Return value of the client. * * @return TRUE: Tell D-Bus that method succeeded. * FALSE: Let D-Bus send an error. * **********************************************************************************************************************/ static gboolean NSMA__boOnHandleLifecycleRequestComplete(NodeStateConsumer *pConsumer, GDBusMethodInvocation *pInvocation, const guint u32RequestId, const gint i32Status, gpointer pUserData) { NsmErrorStatus_e enErrorStatus = NsmErrorStatus_NotSet; /* Check if the client is the one, we are waiting for. */ if(NSMA__pCurrentLcConsumer == (NodeStateLifeCycleConsumer*) u32RequestId) { enErrorStatus = NsmErrorStatus_Ok; /* The client is the expected one. Pass the status to the NSM. */ NSMA__stObjectCallbacks.pfLcClientRequestFinish((NsmErrorStatus_e) i32Status); /* Remove the timeout timer (the expected client returned) */ g_source_remove(NSMA__u32TimerId); } else { enErrorStatus = NsmErrorStatus_Error; } node_state_consumer_complete_lifecycle_request_complete(pConsumer, pInvocation, enErrorStatus); return TRUE; } /********************************************************************************************************************** * * Interfaces. Exported functions. See Header for detailed description. * **********************************************************************************************************************/ gboolean NSMA_boInit(const NSMA_tstObjectCallbacks *pstCallbacks) { /* Initialize glib types */ g_type_init(); /* Initialize file local variables */ NSMA__pMainLoop = NULL; NSMA__pBusConnection = NULL; NSMA__u32ConnectionId = 0; NSMA__boLoopEndByUser = FALSE; NSMA__boInitialized = FALSE; NSMA__pCurrentLcConsumer = NULL; NSMA__pLifecycleControlObj = NULL; NSMA__pNodeStateConsumerObj = NULL; memset(&NSMA__stObjectCallbacks, 0, sizeof(NSMA_tstObjectCallbacks)); /* Check if all callbacks for the NSM have been configured. */ if( (pstCallbacks->pfSetBootModeCb != NULL) && (pstCallbacks->pfSetNodeStateCb != NULL) && (pstCallbacks->pfSetAppModeCb != NULL) && (pstCallbacks->pfRequestNodeRestartCb != NULL) && (pstCallbacks->pfSetAppHealthStatusCb != NULL) && (pstCallbacks->pfCheckLucRequiredCb != NULL) && (pstCallbacks->pfRegisterSessionCb != NULL) && (pstCallbacks->pfUnRegisterSessionCb != NULL) && (pstCallbacks->pfRegisterLifecycleClientCb != NULL) && (pstCallbacks->pfUnRegisterLifecycleClientCb != NULL) && (pstCallbacks->pfGetAppModeCb != NULL) && (pstCallbacks->pfGetSessionStateCb != NULL) && (pstCallbacks->pfGetNodeStateCb != NULL) && (pstCallbacks->pfSetNodeStateCb != NULL) && (pstCallbacks->pfSetSessionStateCb != NULL) && (pstCallbacks->pfGetAppHealthCountCb != NULL) && (pstCallbacks->pfGetInterfaceVersionCb != NULL) && (pstCallbacks->pfLcClientRequestFinish != NULL)) { /* All callbacks are configured. */ NSMA__boInitialized = TRUE; /* Store the passed callbacks. */ memcpy(&NSMA__stObjectCallbacks, pstCallbacks, sizeof(NSMA_tstObjectCallbacks)); /* Create a new main loop */ NSMA__pMainLoop = g_main_loop_new(NULL, FALSE); /* Create D-Bus skeleton objects */ NSMA__pNodeStateConsumerObj = node_state_consumer_skeleton_new(); NSMA__pLifecycleControlObj = node_state_lifecycle_control_skeleton_new(); } else { /* Error: Callbacks are configured incorrectly. */ NSMA__boInitialized = FALSE; } return NSMA__boInitialized; } gboolean NSMA_boWaitForEvents(void) { /* Check if the library has been initialized (objects and callbacks are available) */ if(NSMA__boInitialized == TRUE) { /* Start D-Bus connection sequence */ NSMA__u32ConnectionId = g_bus_own_name((GBusType) NSM_BUS_TYPE, NSM_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, &NSMA__vOnBusAcquired, &NSMA__vOnNameAcquired, &NSMA__vOnNameLost, NULL, NULL); /* Run main loop to get D-Bus connection and export objects. The function will only return, * if there was an internal error or it has been cancelled by the user. */ g_main_loop_run(NSMA__pMainLoop); } else { /* Error: The library has not been initialized. Callbacks and objects are invalid. */ NSMA__boLoopEndByUser = FALSE; } /* Return if function has been cancelled by user (TRUE) or because of an error (FALSE) */ return NSMA__boLoopEndByUser; } gboolean NSMA_boSendNodeStateSignal(const NsmNodeState_e enNodeState) { gboolean boRetVal = FALSE; /* Check if library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Send the signal */ node_state_consumer_emit_node_state(NSMA__pNodeStateConsumerObj, (gint) enNodeState); } else { /* Error: Library not initialized (objects are invalid) */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boSendSessionSignal(const NsmSession_s *pstSession) { gboolean boRetVal = FALSE; /* Check if library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Send the signal */ node_state_consumer_emit_session_state_changed(NSMA__pNodeStateConsumerObj, pstSession->sName, (gint) pstSession->enSeat, (gint) pstSession->enState); } else { /* Error: Library not initialized (objects are invalid) */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boSendApplicationModeSignal(const NsmApplicationMode_e enApplicationMode) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Send the signal */ node_state_consumer_emit_node_application_mode(NSMA__pNodeStateConsumerObj, (gint) enApplicationMode); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boSetBootMode(gint i32BootMode) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Set the properties value */ node_state_consumer_set_boot_mode(NSMA__pNodeStateConsumerObj, i32BootMode); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boGetBootMode(gint *pi32BootMode) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Get the properties value */ *pi32BootMode = node_state_consumer_get_boot_mode(NSMA__pNodeStateConsumerObj); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boSetRunningReason(const NsmRunningReason_e enRunningReason) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Set the properties value */ node_state_consumer_set_wake_up_reason(NSMA__pNodeStateConsumerObj, (gint) enRunningReason); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boGetRunningReason(NsmRunningReason_e *penRunningReason) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Get the properties value */ *penRunningReason = (NsmRunningReason_e) node_state_consumer_get_wake_up_reason(NSMA__pNodeStateConsumerObj); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boSetShutdownReason(const NsmShutdownReason_e enShutdownReason) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Set the properties value */ node_state_consumer_set_shutdown_reason(NSMA__pNodeStateConsumerObj, (gint) enShutdownReason); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boGetShutdownReason(NsmShutdownReason_e *penShutdownReason) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Get the properties value */ *penShutdownReason = (NsmShutdownReason_e) node_state_consumer_get_shutdown_reason(NSMA__pNodeStateConsumerObj); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boSetRestartReason(const NsmRestartReason_e enRestartReason) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Set the properties value */ node_state_consumer_set_restart_reason(NSMA__pNodeStateConsumerObj, (gint) enRestartReason); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boGetRestartReason(NsmRestartReason_e *penRestartReason) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { boRetVal = TRUE; /* Get the properties value */ *penRestartReason = (NsmRestartReason_e) node_state_consumer_get_restart_reason(NSMA__pNodeStateConsumerObj); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boQuitEventLoop(void) { gboolean boRetVal = FALSE; /* Check if the library has been initialized (objects are available) */ if(NSMA__boInitialized == TRUE) { NSMA__boLoopEndByUser = TRUE; g_main_loop_quit(NSMA__pMainLoop); } else { /* Error: Library not initialized. Objects are invalid. */ boRetVal = FALSE; } return boRetVal; } gboolean NSMA_boFreeLcConsumerProxy(NSMA_tLcConsumerHandle hLcConsumer) { g_object_unref(hLcConsumer); return TRUE; } NSMA_tLcConsumerHandle NSMA_hCreateLcConsumer(const gchar* sBusName, const gchar* sObjName, const guint u32TimeoutMs) { NodeStateLifeCycleConsumer *pConsumerProxy = NULL; pConsumerProxy = node_state_life_cycle_consumer_proxy_new_sync(NSMA__pBusConnection, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, sBusName, sObjName, NULL, NULL); if(pConsumerProxy != NULL) { g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(pConsumerProxy), u32TimeoutMs); } return (NSMA_tLcConsumerHandle) pConsumerProxy; } gboolean NSMA_boCallLcClientRequest(NSMA_tLcConsumerHandle hLcClient, guint u32ShutdownType) { NSMA__pCurrentLcConsumer = (NodeStateLifeCycleConsumer*) hLcClient; node_state_life_cycle_consumer_call_lifecycle_request(NSMA__pCurrentLcConsumer, u32ShutdownType, (guint) NSMA__pCurrentLcConsumer, NULL, &NSMA__vOnLifecycleRequestFinish, NULL); return TRUE; } gboolean NSMA_boSetLcClientTimeout(NSMA_tLcConsumerHandle hClient, guint u32TimeoutMs) { g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(hClient), u32TimeoutMs); return TRUE; } gboolean NSMA_boGetLcClientTimeout(NSMA_tLcConsumerHandle hClient, guint *pu32TimeoutMs) { *pu32TimeoutMs = g_dbus_proxy_get_default_timeout(G_DBUS_PROXY(hClient)); return TRUE; } gboolean NSMA_boDeInit(void) { NSMA__boInitialized = FALSE; g_bus_unown_name(NSMA__u32ConnectionId); g_main_loop_unref(NSMA__pMainLoop); /* Release the (created) skeleton objects */ if(NSMA__pNodeStateConsumerObj != NULL) { g_object_unref(NSMA__pNodeStateConsumerObj); } if(NSMA__pLifecycleControlObj != NULL) { g_object_unref(NSMA__pLifecycleControlObj); } return TRUE; }