* Company XS Embedded GmbH
*****************************************************************************/
/******************************************************************************
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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/.
******************************************************************************/
/**
* @file persistence_client_library_dbus_service.c
* @see
*/
-//#include "persistence_client_service_dbus_service.h"
#include "persistence_client_library_dbus_service.h"
#include "persistence_client_library_lc_interface.h"
#include "persistence_client_library_pas_interface.h"
+#include "persistence_client_library_dbus_cmd.h"
+#include "persistence_client_library_data_organization.h"
+
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
-#include <pthread.h>
-/// polling structure
-typedef struct SPollInfo
-{
- int nfds;
- struct pollfd fds[10];
- DBusWatch * watches[10];
-} tPollInfo;
+pthread_cond_t gDbusInitializedCond = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t gDbusInitializedMtx = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t gDbusPendingRegMtx = PTHREAD_MUTEX_INITIALIZER;
-/// polling information
-static tPollInfo gPollInfo;
+pthread_mutex_t gDeliverpMtx = PTHREAD_MUTEX_INITIALIZER;
+
+pthread_mutex_t gMainCondMtx = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t gMainLoopCond = PTHREAD_COND_INITIALIZER;
+
+pthread_t gMainLoopThread;
-/// dbus connection
-DBusConnection* gDbusConn = NULL;
+int gEfds; // communication channel int dbus mainloop
-DBusConnection* get_dbus_connection()
+
+typedef enum EDBusObjectType
{
- return gDbusConn;
-}
+ OT_NONE = 0,
+ OT_WATCH,
+ OT_TIMEOUT
+} tDBusObjectType;
-//------------------------------------------------------------------------
-// debugging only until "correct" exit of main loop is possible!!!!!
-//------------------------------------------------------------------------
-#include "signal.h"
-static int endLoop = 0;
-void sigHandler(int signo)
+typedef struct SObjectEntry
{
- endLoop = 1;
-}
-//------------------------------------------------------------------------
+ tDBusObjectType objtype; /** libdbus' object */
+ union
+ {
+ DBusWatch * watch; /** watch "object" */
+ DBusTimeout * timeout; /** timeout "object" */
+ };
+} tObjectEntry;
-//const char* gPersDbusAdminInterface = "org.genivi.persistence.admin";
-//const char* gPersDbusAdminPath = "/org/genivi/persistence/admin";
+/// polling structure
+typedef struct SPollInfo
+{
+ int nfds;
+ struct pollfd fds[10];
+ tObjectEntry objects[10];
+} tPollInfo;
+
+
+/// polling information
+static tPollInfo gPollInfo;
+
+int bContinue = 0;
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
/* function to unregister ojbect path message handler */
static void unregisterMessageHandler(DBusConnection *connection, void *user_data)
{
- printf("unregisterObjectPath\n");
+ (void)connection;
+ (void)user_data;
+ DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("unregisterObjectPath\n"));
}
/* catches messages not directed to any registered object path ("garbage collector") */
static DBusHandlerResult handleObjectPathMessageFallback(DBusConnection * connection, DBusMessage * message, void * user_data)
{
- printf("handleObjectPathMessageFallback '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message) );
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
+ (void)user_data;
+
+ // org.genivi.persistence.admin S I G N A L
+ if((0==strcmp("org.genivi.persistence.admin", dbus_message_get_interface(message))))
+ {
+ if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
+ {
+ if((0==strcmp("PersistenceModeChanged", dbus_message_get_member(message))))
+ {
+ // to do handle signal
+ result = signal_persModeChange(connection, message);
+ }
+ else
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback -> unknown signal:"), DLT_STRING(dbus_message_get_interface(message)) );
+ }
+ }
+ }
+ // org.genivi.persistence.admin S I G N A L
+ else if((0==strcmp("org.genivi.persistence.adminconsumer", dbus_message_get_interface(message))))
+ {
+ if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
+ {
+ pclNotification_s notifyStruct;
+ int validMessage = 0;
+
+ if((0==strcmp("PersistenceResChange", dbus_message_get_member(message))))
+ {
+ notifyStruct.pclKeyNotify_Status = pclNotifyStatus_changed;
+ validMessage = 1;
+ }
+ else if((0==strcmp("PersistenceResDelete", dbus_message_get_member(message))))
+ {
+ notifyStruct.pclKeyNotify_Status = pclNotifyStatus_deleted;
+ validMessage = 1;
+ }
+ else if((0==strcmp("PersistenceRes", dbus_message_get_member(message))))
+ {
+ notifyStruct.pclKeyNotify_Status = pclNotifyStatus_created;
+ validMessage = 1;
+ }
+
+ if(validMessage == 1)
+ {
+ DBusError error;
+ DBusMessage *reply;
+ dbus_error_init (&error);
+ char* ldbid;
+ char* user_no;
+ char* seat_no;
+
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, ¬ifyStruct.resource_id,
+ DBUS_TYPE_STRING, &ldbid,
+ DBUS_TYPE_STRING, &user_no,
+ DBUS_TYPE_STRING, &seat_no,
+ DBUS_TYPE_INVALID))
+ {
+ reply = dbus_message_new_error(message, error.name, error.message);
+
+ if (reply == 0)
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback => DBus No memory"), DLT_STRING(dbus_message_get_interface(message)) );
+ }
+
+ if (!dbus_connection_send(connection, reply, 0))
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback => DBus No memory"), DLT_STRING(dbus_message_get_interface(message)) );
+ }
+
+ result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;;
+ dbus_message_unref(reply);
+ }
+ else
+ {
+ notifyStruct.ldbid = atoi(ldbid);
+ notifyStruct.user_no = atoi(user_no);
+ notifyStruct.seat_no = atoi(seat_no);
+
+ // call the registered callback function
+ if(gChangeNotifyCallback != NULL )
+ {
+ gChangeNotifyCallback(¬ifyStruct);
+ }
+ else
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback => gChangeNotifyCallback is not set (possibly NULL)") );
+ }
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ dbus_connection_flush(connection);
+ }
+ }
+ }
+ // org.genivi.persistence.admin P R O P E R T Y
+ else if((0==strcmp("org.freedesktop.DBus.Properties", dbus_message_get_interface(message))))
+ {
+ if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
+ {
+ if((0==strcmp("EggDBusChanged", dbus_message_get_member(message))))
+ {
+ DBusMessageIter array;
+ DBusMessageIter dict;
+ DBusMessageIter variant;
+
+ char* dictString = NULL;
+ int value = 0;
+
+ dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, 0, &dict);
+ dbus_message_iter_get_basic(&dict, &dictString);
+
+ dbus_message_iter_open_container(&dict,DBUS_TYPE_VARIANT, NULL, &variant);
+ dbus_message_iter_get_basic(&dict, &value);
+
+ dbus_message_iter_close_container(&dict, &variant);
+ dbus_message_iter_close_container(&array, &dict);
+
+ // to do handle signal
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback -> unknown property:"), DLT_STRING(dbus_message_get_interface(message)) );
+ }
+ }
+ else
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback -> not a signal:"), DLT_STRING(dbus_message_get_member(message)) );
+ }
+ }
+ return result;
}
static void unregisterObjectPathFallback(DBusConnection *connection, void *user_data)
{
- printf("unregisterObjectPathFallback\n");
+ (void)connection;
+ (void)user_data;
+ DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("unregisterObjectPathFallback\n"));
}
{
// persistence admin message
static const struct DBusObjectPathVTable vtablePersAdmin
- = {unregisterMessageHandler, checkPersAdminMsg, NULL, };
+ = {unregisterMessageHandler, checkPersAdminMsg, NULL, NULL, NULL, NULL};
// lifecycle message
static const struct DBusObjectPathVTable vtableLifecycle
- = {unregisterMessageHandler, checkLifecycleMsg, NULL, };
+ = {unregisterMessageHandler, checkLifecycleMsg, NULL, NULL, NULL, NULL};
// fallback
static const struct DBusObjectPathVTable vtableFallback
- = {unregisterObjectPathFallback, handleObjectPathMessageFallback, NULL, };
+ = {unregisterObjectPathFallback, handleObjectPathMessageFallback, NULL, NULL, NULL, NULL};
// setup the dbus
mainLoop(vtablePersAdmin, vtableLifecycle, vtableFallback, dataPtr);
- printf("Exit dbus main loop!!!!\n");
-
return NULL;
}
-int setup_dbus_mainloop()
+int setup_dbus_mainloop(void)
{
int rval = 0;
- pthread_t thread;
DBusError err;
+ DBusConnection* conn = NULL;
+
const char *pAddress = getenv("PERS_CLIENT_DBUS_ADDRESS");
+
dbus_error_init(&err);
+ // wait until dbus main loop has been setup and running
+ pthread_mutex_lock(&gDbusInitializedMtx);
+
// Connect to the bus and check for errors
if(pAddress != NULL)
{
- printf("Use specific dbus address: %s\n !", pAddress);
- gDbusConn = dbus_connection_open(pAddress, &err);
+ DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("setup_dbus_mainloop -> Use specific dbus address:"), DLT_STRING(pAddress) );
- if(gDbusConn != NULL)
+ conn = dbus_connection_open_private(pAddress, &err);
+
+ if(conn != NULL)
{
- if(!dbus_bus_register(gDbusConn, &err))
+ if(!dbus_bus_register(conn, &err))
{
- printf("dbus_bus_register() Error %s\n", err.message);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("dbus_bus_register() Error :"), DLT_STRING(err.message) );
dbus_error_free (&err);
+ pthread_mutex_unlock(&gDbusInitializedMtx);
return -1;
}
- else
- {
- printf("Registered connection successfully !\n");
- }
}
else
{
- printf("dbus_connection_open() Error %s\n",err.message);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("dbus_connection_open_private() Error :"), DLT_STRING(err.message) );
dbus_error_free(&err);
+ pthread_mutex_unlock(&gDbusInitializedMtx);
+ return -1;
}
}
else
{
- printf("Use default dbus bus!!!!!!\n");
- gDbusConn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Use default dbus bus (DBUS_BUS_SYSTEM)"));
+
+ conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
}
// create here the dbus connection and pass to main loop
- rval = pthread_create(&thread, NULL, run_mainloop, gDbusConn);
-
- if (rval)
+ rval = pthread_create(&gMainLoopThread, NULL, run_mainloop, conn);
+ if(rval)
{
- fprintf(stderr, "Server: - ERROR! pthread_create( run_mainloop ) returned: %d\n", rval);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pthread_create( DBUS run_mainloop ) returned an error:"), DLT_INT(rval) );
+ pthread_mutex_unlock(&gDbusInitializedMtx);
+ return -1;
}
+
+ // wait for condition variable
+ pthread_cond_wait(&gDbusInitializedCond, &gDbusInitializedMtx);
+
+ pthread_mutex_unlock(&gDbusInitializedMtx);
return rval;
}
static dbus_bool_t addWatch(DBusWatch *watch, void *data)
{
dbus_bool_t result = FALSE;
-
- //printf("addWatch called @%08x flags: %08x enabled: %c\n", (unsigned int)watch, dbus_watch_get_flags(watch), TRUE==dbus_watch_get_enabled(watch)?'x':'-');
+ (void)data;
if (ARRAY_SIZE(gPollInfo.fds)>gPollInfo.nfds)
{
int flags = dbus_watch_get_flags(watch);
- gPollInfo.watches[gPollInfo.nfds] = watch;
+ tObjectEntry * const pEntry = &gPollInfo.objects[gPollInfo.nfds];
+ pEntry->objtype = OT_WATCH;
+ pEntry->watch = watch;
gPollInfo.fds[gPollInfo.nfds].fd = dbus_watch_get_unix_fd(watch);
}
++gPollInfo.nfds;
-
- static const int cmd = CMD_REQUEST_NAME;
- if (sizeof(int)!=write(gPipefds[1], &cmd, sizeof(int)))
- {
- printf("write failed w/ errno %d\n", errno);
- }
}
result = TRUE;
static void removeWatch(DBusWatch *watch, void *data)
{
- printf("removeWatch called @0x%08x\n", (int)watch);
+ void* w_data = dbus_watch_get_data(watch);
+
+ (void)data;
+
+ DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("removeWatch called "), DLT_INT( (int)watch) );
+
+ if(w_data)
+ free(w_data);
+
+ dbus_watch_set_data(watch, NULL, NULL);
}
static void watchToggled(DBusWatch *watch, void *data)
{
- printf("watchToggled called @0x%08x\n", (int)watch);
+ (void)data;
+ DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("watchToggled called "), DLT_INT( (int)watch) );
+
+ if(dbus_watch_get_enabled(watch))
+ addWatch(watch, data);
+ else
+ removeWatch(watch, data);
+}
+
+
+
+static dbus_bool_t addTimeout(DBusTimeout *timeout, void *data)
+{
+ (void)data;
+ dbus_bool_t ret = FALSE;
+
+ if (ARRAY_SIZE(gPollInfo.fds)>gPollInfo.nfds)
+ {
+ const int interval = dbus_timeout_get_interval(timeout);
+ if ((0<interval)&&(TRUE==dbus_timeout_get_enabled(timeout)))
+ {
+ const int tfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+ if (-1!=tfd)
+ {
+ const struct itimerspec its = { .it_value= {interval/1000, interval%1000} };
+ if (-1!=timerfd_settime(tfd, 0, &its, NULL))
+ {
+ tObjectEntry * const pEntry = &gPollInfo.objects[gPollInfo.nfds];
+ pEntry->objtype = OT_TIMEOUT;
+ pEntry->timeout = timeout;
+ gPollInfo.fds[gPollInfo.nfds].fd = tfd;
+ gPollInfo.fds[gPollInfo.nfds].events |= POLLIN;
+ ++gPollInfo.nfds;
+ ret = TRUE;
+ }
+ else
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("addTimeout => timerfd_settime() failed"), DLT_STRING(strerror(errno)) );
+ }
+ }
+ else
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("addTimeout => timerfd_create() failed"), DLT_STRING(strerror(errno)) );
+ }
+ }
+ }
+ else
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("addTimeout => cannot create another fd to be poll()'ed"));
+ }
+
+ return ret;
+}
+
+
+
+static void removeTimeout(DBusTimeout *timeout, void *data)
+{
+ int i = gPollInfo.nfds;
+ (void)data;
+
+ while ((0<i--)&&(timeout!=gPollInfo.objects[i].timeout));
+
+ if (0<i)
+ {
+ if (-1==close(gPollInfo.fds[i].fd))
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("removeTimeout => close() timerfd"), DLT_STRING(strerror(errno)) );
+ }
+
+ --gPollInfo.nfds;
+ while (gPollInfo.nfds>i)
+ {
+ gPollInfo.fds[i] = gPollInfo.fds[i+1];
+ gPollInfo.objects[i] = gPollInfo.objects[i+1];
+ ++i;
+ }
+
+ gPollInfo.fds[gPollInfo.nfds].fd = -1;
+ gPollInfo.objects[gPollInfo.nfds].objtype = OT_NONE;
+ }
+}
+
+
+
+/** callback for libdbus' when timeout changed */
+static void timeoutToggled(DBusTimeout *timeout, void *data)
+{
+ int i = gPollInfo.nfds;
+ (void)data;
+
+ while ((0<i--)&&(timeout!=gPollInfo.objects[i].timeout));
+ DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("timeoutToggled") );
+ if (0<i)
+ {
+ const int interval = (TRUE==dbus_timeout_get_enabled(timeout))?dbus_timeout_get_interval(timeout):0;
+ const struct itimerspec its = { .it_value= {interval/1000, interval%1000} };
+ if (-1!=timerfd_settime(gPollInfo.fds[i].fd, 0, &its, NULL))
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("timeoutToggled => timerfd_settime()"), DLT_STRING(strerror(errno)) );
+ }
+ }
}
DBusObjectPathVTable vtableFallback, void* userData)
{
DBusError err;
-
- signal(SIGTERM, sigHandler);
- signal(SIGQUIT, sigHandler);
- signal(SIGINT, sigHandler);
+ // lock mutex to make sure dbus main loop is running
+ pthread_mutex_lock(&gDbusInitializedMtx);
DBusConnection* conn = (DBusConnection*)userData;
-
dbus_error_init(&err);
if (dbus_error_is_set(&err))
{
- printf("Connection Error (%s)\n", err.message);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => Connection Error:"), DLT_STRING(err.message) );
dbus_error_free(&err);
}
else if (NULL != conn)
{
- dbus_connection_set_exit_on_disconnect (conn, FALSE);
-
- printf("connected as '%s'\n", dbus_bus_get_unique_name(conn));
-
- if (0!=pipe(gPipefds))
+ dbus_connection_set_exit_on_disconnect(conn, FALSE);
+ if (-1 == (gEfds = eventfd(0, 0)))
{
- printf("pipe() failed w/ errno %d\n", errno);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => eventfd() failed w/ errno:"), DLT_INT(errno) );
}
else
{
int ret;
- int bContinue = 0;
memset(&gPollInfo, 0 , sizeof(gPollInfo));
gPollInfo.nfds = 1;
- gPollInfo.fds[0].fd = gPipefds[0];
+ gPollInfo.fds[0].fd = gEfds;
gPollInfo.fds[0].events = POLLIN;
- if ( (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/persistence/adminconsumer", &vtable, userData))
- && (TRUE==dbus_connection_register_object_path(conn, "/com/contiautomotive/NodeStateManager/LifecycleConsumer", &vtable2, userData))
+ dbus_bus_add_match(conn, "type='signal',interface='org.genivi.persistence.admin',member='PersistenceModeChanged',path='/org/genivi/persistence/admin'", &err);
+
+ // register for messages
+ if ( (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/NodeStateManager/LifeCycleConsumer", &vtable2, userData))
+#if USE_PASINTERFACE == 1
+ && (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/persistence/adminconsumer", &vtable, userData))
+#endif
&& (TRUE==dbus_connection_register_fallback(conn, "/", &vtableFallback, userData)) )
{
- if (TRUE!=dbus_connection_set_watch_functions(conn, addWatch, removeWatch, watchToggled, NULL, NULL))
+ if( (TRUE!=dbus_connection_set_watch_functions(conn, addWatch, removeWatch, watchToggled, NULL, NULL))
+ || (TRUE!=dbus_connection_set_timeout_functions(conn, addTimeout, removeTimeout, timeoutToggled, NULL, NULL)) )
{
- printf("dbus_connection_set_watch_functions() failed\n");
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => dbus_connection_set_watch_functions() failed"));
}
else
{
- char buf[64];
-
+ pthread_cond_signal(&gDbusInitializedCond);
+ pthread_mutex_unlock(&gDbusInitializedMtx);
do
{
bContinue = 0; /* assume error */
while (DBUS_DISPATCH_DATA_REMAINS==dbus_connection_dispatch(conn));
- while ((-1==(ret=poll(gPollInfo.fds, gPollInfo.nfds, 500)))&&(EINTR==errno));
+ while ((-1==(ret=poll(gPollInfo.fds, gPollInfo.nfds, 750)))&&(EINTR==errno));
- if(0>ret)
+ if (0>ret)
{
- printf("poll() failed w/ errno %d\n", errno);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => poll() failed w/ errno "), DLT_INT(errno) );
+ }
+ else if (0==ret)
+ {
+ /* poll time-out */
}
else
{
int i;
- bContinue = 1;
for (i=0; gPollInfo.nfds>i; ++i)
{
+ /* anything to do */
if (0!=gPollInfo.fds[i].revents)
{
- if (gPollInfo.fds[i].fd==gPipefds[0])
+ if (OT_TIMEOUT==gPollInfo.objects[i].objtype)
+ {
+ /* time-out occured */
+ unsigned long long nExpCount = 0;
+ if ((ssize_t)sizeof(nExpCount)!=read(gPollInfo.fds[i].fd, &nExpCount, sizeof(nExpCount)))
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => read failed"));
+ }
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => timeout"));
+
+ if (FALSE==dbus_timeout_handle(gPollInfo.objects[i].timeout))
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => dbus_timeout_handle() failed!?"));
+ }
+ bContinue = TRUE;
+ }
+ else if (gPollInfo.fds[i].fd == gEfds)
{
+ /* internal command */
if (0!=(gPollInfo.fds[i].revents & POLLIN))
{
+ uint16_t buf[64];
bContinue = TRUE;
- while ((-1==(ret=read(gPollInfo.fds[i].fd, buf, 64)))&&(EINTR==errno));
- if (0>ret)
+ while ((-1==(ret = read(gPollInfo.fds[i].fd, buf, 64)))&&(EINTR == errno));
+ if(ret < 0)
{
- printf("read() failed w/ errno %d\n", errno);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => read() failed"), DLT_STRING(strerror(errno)) );
}
- else if (sizeof(int)==ret)
+ else
{
+ pthread_mutex_lock(&gMainCondMtx);
switch (buf[0])
{
- case CMD_REQUEST_NAME:
- if(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
- != dbus_bus_request_name(conn, "org.genivi.persistence.adminconsumer", DBUS_NAME_FLAG_DO_NOT_QUEUE, &err))
- {
- printf("*** Cannot acquire name '%s' (%s). Bailing out!\n", "org.genivi.persistence.admin\n", err.message);
- dbus_error_free(&err);
- bContinue = FALSE;
- }
- if(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
- != dbus_bus_request_name(conn, "com.contiautomotive.NodeStateManager.LifecycleConsumer", DBUS_NAME_FLAG_DO_NOT_QUEUE, &err))
- {
- printf("*** Cannot acquire name '%s' (%s). Bailing out!\n", "com.contiautomotive.NodeStateManager.LifecycleConsumer\n", err.message);
- dbus_error_free(&err);
- bContinue = FALSE;
- }
- break;
case CMD_PAS_BLOCK_AND_WRITE_BACK:
- process_block_and_write_data_back();
+ process_block_and_write_data_back((buf[2]), buf[1]);
+ process_send_pas_request(conn, (buf[2]), buf[1]);
break;
case CMD_LC_PREPARE_SHUTDOWN:
- process_prepare_shutdown(buf[1]);
+ process_prepare_shutdown(Shutdown_Full);
+ process_send_lifecycle_request(conn, (buf[2]), buf[1]);
+ break;
+ case CMD_SEND_NOTIFY_SIGNAL:
+ process_send_notification_signal(conn);
+ break;
+ case CMD_REG_NOTIFY_SIGNAL:
+ process_reg_notification_signal(conn);
+ break;
+ case CMD_SEND_PAS_REGISTER:
+ process_send_pas_register(conn, (buf[1]), buf[2]);
+ break;
+ case CMD_SEND_LC_REGISTER:
+ process_send_lifecycle_register(conn, (buf[1]), buf[2]);
break;
case CMD_QUIT:
- bContinue = FALSE;
+ bContinue = 0;
break;
+
+ // ******************************************************
+ /*
+ case CMD_SEND_LC_REQUEST: // remove
+ process_send_lifecycle_request(conn, (buf[2]), buf[1]);
+ break;
+ case CMD_SEND_PAS_REQUEST: /// remove
+ process_send_pas_request(conn, (buf[2]), buf[1]);
+ break;
+ */
+ // ******************************************************
default:
- printf("command %d not handled!\n", buf[0]);
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => command not handled"), DLT_INT(buf[0]) );
break;
}
- }
- else
- {
- printf("read() returned %d (%s)\n", ret, buf);
+ pthread_cond_signal(&gMainLoopCond);
+ pthread_mutex_unlock(&gMainCondMtx);
}
}
}
{
flags |= DBUS_WATCH_HANGUP;
}
- //printf("handle watch @0x%08x flags: %04x\n", (int)gPollInfo.watches[i], flags);
- bContinue = dbus_watch_handle(gPollInfo.watches[i], flags);
+
+ bContinue = dbus_watch_handle(gPollInfo.objects[i].watch, flags);
}
}
}
}
- if(endLoop == 1)
- break;
}
while (0!=bContinue);
}
+#if USE_PASINTERFACE == 1
dbus_connection_unregister_object_path(conn, "/org/genivi/persistence/adminconsumer");
- //dbus_connection_unregister_object_path(conn, "/com/");
+#endif
+ dbus_connection_unregister_object_path(conn, "/org/genivi/NodeStateManager/LifeCycleConsumer");
dbus_connection_unregister_object_path(conn, "/");
}
- close(gPipefds[1]);
- close(gPipefds[0]);
+ close(gEfds);
}
+ dbus_connection_close(conn);
dbus_connection_unref(conn);
dbus_shutdown();
}
+
+ pthread_cond_signal(&gDbusInitializedCond);
+ pthread_mutex_unlock(&gDbusInitializedMtx);
return 0;
}
+
+
+int deliverToMainloop(tCmd mainloopCmd, unsigned int param1, unsigned int param2)
+{
+ int rval = 0;
+
+ pthread_mutex_lock(&gDeliverpMtx);
+
+
+ pthread_mutex_lock(&gMainCondMtx);
+
+ deliverToMainloop_NM(mainloopCmd, param1, param2);
+
+ pthread_cond_wait(&gMainLoopCond, &gMainCondMtx);
+ pthread_mutex_unlock(&gMainCondMtx);
+
+
+ pthread_mutex_unlock(&gDeliverpMtx);
+
+ return rval;
+}
+
+int deliverToMainloop_NM(tCmd mainloopCmd, unsigned int param1, unsigned int param2)
+{
+ int rval = 0;
+ uint64_t cmd;
+
+ cmd = ( ((uint64_t)param2 << 32) | ((uint64_t)param1 << 16) | mainloopCmd);
+
+ if(-1 == write(gEfds, &cmd, (sizeof(uint64_t))))
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("deliverToMainloop => failed to write to pipe"), DLT_INT(errno));
+ rval = -1;
+ }
+
+ return rval;
+}
+