aade4d3c7bb76ddf8af88b881bd1d2a8376c8a03
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_dbus_service.c
1 /******************************************************************************
2  * Project         Persistency
3  * (c) copyright   2012
4  * Company         XS Embedded GmbH
5  *****************************************************************************/
6 /******************************************************************************
7  * This Source Code Form is subject to the terms of the
8  * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed
9  * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 ******************************************************************************/
11  /**
12  * @file           persistence_client_library_dbus_service.c
13  * @ingroup        Persistence client library
14  * @author         Ingo Huerner
15  * @brief          Implementation of the persistence client library dbus service.
16  * @see
17  */
18
19
20 #include "persistence_client_library_dbus_service.h"
21 #include "persistence_client_library_lc_interface.h"
22 #include "persistence_client_library_pas_interface.h"
23 #include "../include_protected/persistence_client_library_data_organization.h"
24
25 #include <stdio.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30
31 pthread_cond_t  gDbusInitializedCond = PTHREAD_COND_INITIALIZER;
32 pthread_mutex_t gDbusInitializedMtx  = PTHREAD_MUTEX_INITIALIZER;
33 pthread_mutex_t gDbusPendingRegMtx   = PTHREAD_MUTEX_INITIALIZER;
34 pthread_mutex_t gMainLoopMtx         = PTHREAD_MUTEX_INITIALIZER;
35
36 int gEfds;
37
38
39 typedef enum EDBusObjectType
40 {
41    OT_NONE = 0,
42    OT_WATCH,
43    OT_TIMEOUT
44 } tDBusObjectType;
45
46
47 typedef struct SObjectEntry
48 {
49    tDBusObjectType objtype; /** libdbus' object */
50    union
51    {
52       DBusWatch * watch;      /** watch "object" */
53       DBusTimeout * timeout;  /** timeout "object" */
54    };
55 } tObjectEntry;
56
57
58
59 /// polling structure
60 typedef struct SPollInfo
61 {
62    int nfds;
63    struct pollfd fds[10];
64    tObjectEntry objects[10];
65 } tPollInfo;
66
67
68 /// polling information
69 static tPollInfo gPollInfo;
70
71 int bContinue = 0;
72
73 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
74
75
76 /* function to unregister ojbect path message handler */
77 static void unregisterMessageHandler(DBusConnection *connection, void *user_data)
78 {
79    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("unregisterObjectPath\n"));
80 }
81
82 /* catches messages not directed to any registered object path ("garbage collector") */
83 static DBusHandlerResult handleObjectPathMessageFallback(DBusConnection * connection, DBusMessage * message, void * user_data)
84 {
85    DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
86
87    // org.genivi.persistence.admin  S I G N A L
88    if((0==strcmp("org.genivi.persistence.admin", dbus_message_get_interface(message))))
89    {
90       if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
91       {
92          if((0==strcmp("PersistenceModeChanged", dbus_message_get_member(message))))
93          {
94             // to do handle signal
95             result = signal_persModeChange(connection, message);
96          }
97          else
98          {
99             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback -> unknown signal:"), DLT_STRING(dbus_message_get_interface(message)) );
100          }
101       }
102    }
103    // org.genivi.persistence.admin  S I G N A L
104    else if((0==strcmp("org.genivi.persistence.adminconsumer", dbus_message_get_interface(message))))
105    {
106       if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
107       {
108          pclNotification_s notifyStruct;
109          int validMessage = 0;
110
111          if((0==strcmp("PersistenceResChange", dbus_message_get_member(message))))
112          {
113             notifyStruct.pclKeyNotify_Status = pclNotifyStatus_changed;
114             validMessage = 1;
115          }
116          else if((0==strcmp("PersistenceResDelete", dbus_message_get_member(message))))
117          {
118             notifyStruct.pclKeyNotify_Status = pclNotifyStatus_deleted;
119             validMessage = 1;
120          }
121          else if((0==strcmp("PersistenceRes", dbus_message_get_member(message))))
122          {
123             notifyStruct.pclKeyNotify_Status = pclNotifyStatus_created;
124             validMessage = 1;
125          }
126
127          if(validMessage == 1)
128          {
129             DBusError error;
130             DBusMessage *reply;
131             dbus_error_init (&error);
132             char* ldbid;
133             char* user_no;
134             char* seat_no;
135
136             if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &notifyStruct.resource_id,
137                                                          DBUS_TYPE_STRING, &ldbid,
138                                                          DBUS_TYPE_STRING, &user_no,
139                                                          DBUS_TYPE_STRING, &seat_no,
140                                                          DBUS_TYPE_INVALID))
141             {
142                reply = dbus_message_new_error(message, error.name, error.message);
143
144                if (reply == 0)
145                {
146                   DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback => DBus No memory"), DLT_STRING(dbus_message_get_interface(message)) );
147                }
148
149                if (!dbus_connection_send(connection, reply, 0))
150                {
151                   DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback => DBus No memory"), DLT_STRING(dbus_message_get_interface(message)) );
152                }
153
154                result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;;
155                dbus_message_unref(reply);
156             }
157             else
158             {
159                notifyStruct.ldbid       = atoi(ldbid);
160                notifyStruct.user_no     = atoi(user_no);
161                notifyStruct.seat_no     = atoi(seat_no);
162
163                // call the registered callback function
164                if(gChangeNotifyCallback != NULL )
165                {
166                   gChangeNotifyCallback(&notifyStruct);
167                }
168                else
169                {
170                   DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback => gChangeNotifyCallback is not set (possibly NULL)") );
171                }
172                result = DBUS_HANDLER_RESULT_HANDLED;
173             }
174             dbus_connection_flush(connection);
175          }
176       }
177    }
178    // org.genivi.persistence.admin  P R O P E R T Y
179    else  if((0==strcmp("org.freedesktop.DBus.Properties", dbus_message_get_interface(message))))
180    {
181       if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
182       {
183          if((0==strcmp("EggDBusChanged", dbus_message_get_member(message))))
184          {
185             DBusMessageIter array;
186             DBusMessageIter dict;
187             DBusMessageIter variant;
188
189             char* dictString = NULL;
190             int value = 0;
191
192             dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, 0, &dict);
193             dbus_message_iter_get_basic(&dict, &dictString);
194
195             dbus_message_iter_open_container(&dict,DBUS_TYPE_VARIANT, NULL, &variant);
196             dbus_message_iter_get_basic(&dict, &value);
197
198             dbus_message_iter_close_container(&dict, &variant);
199             dbus_message_iter_close_container(&array, &dict);
200
201             // to do handle signal
202             result = DBUS_HANDLER_RESULT_HANDLED;
203          }
204          else
205          {
206             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback -> unknown property:"), DLT_STRING(dbus_message_get_interface(message)) );
207          }
208       }
209       else
210       {
211          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("handleObjectPathMessageFallback -> not a signal:"), DLT_STRING(dbus_message_get_member(message)) );
212       }
213    }
214    return result;
215 }
216
217
218
219 static void  unregisterObjectPathFallback(DBusConnection *connection, void *user_data)
220 {
221    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("unregisterObjectPathFallback\n"));
222 }
223
224
225
226 void* run_mainloop(void* dataPtr)
227 {
228    // persistence admin message
229    static const struct DBusObjectPathVTable vtablePersAdmin
230       = {unregisterMessageHandler, checkPersAdminMsg, NULL, };
231
232    // lifecycle message
233    static const struct DBusObjectPathVTable vtableLifecycle
234       = {unregisterMessageHandler, checkLifecycleMsg, NULL, };
235
236    // fallback
237    static const struct DBusObjectPathVTable vtableFallback
238       = {unregisterObjectPathFallback, handleObjectPathMessageFallback, NULL, };
239
240    // setup the dbus
241    mainLoop(vtablePersAdmin, vtableLifecycle, vtableFallback, dataPtr);
242
243    return NULL;
244 }
245
246
247
248 int setup_dbus_mainloop(void)
249 {
250    int rval = 0;
251    pthread_t thread;
252    DBusError err;
253    DBusConnection* conn = NULL;
254
255    const char *pAddress = getenv("PERS_CLIENT_DBUS_ADDRESS");
256
257    // enable locking of data structures in the D-Bus library for multi threading.
258    dbus_threads_init_default();
259    dbus_error_init(&err);
260
261    // wain until dbus main loop has been setup and running
262    pthread_mutex_lock(&gDbusInitializedMtx);
263
264    // Connect to the bus and check for errors
265    if(pAddress != NULL)
266    {
267       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("setup_dbus_mainloop -> Use specific dbus address:"), DLT_STRING(pAddress) );
268
269       conn = dbus_connection_open_private(pAddress, &err);
270
271       if(conn != NULL)
272       {
273          if(!dbus_bus_register(conn, &err))
274          {
275             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("dbus_bus_register() Error :"), DLT_STRING(err.message) );
276             dbus_error_free (&err);
277             return -1;
278          }
279       }
280       else
281       {
282          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("dbus_connection_open_private() Error :"), DLT_STRING(err.message) );
283          dbus_error_free(&err);
284          return -1;
285       }
286    }
287    else
288    {
289       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("Use default dbus bus (DBUS_BUS_SYSTEM)"));
290
291       conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
292    }
293
294    // create here the dbus connection and pass to main loop
295    rval = pthread_create(&thread, NULL, run_mainloop, conn);
296    if(rval)
297    {
298      DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pthread_create( DBUS run_mainloop ) returned an error:"), DLT_INT(rval) );
299      return -1;
300    }
301
302    // wait for condition variable
303    pthread_cond_wait(&gDbusInitializedCond, &gDbusInitializedMtx);
304
305    pthread_mutex_unlock(&gDbusInitializedMtx);
306    return rval;
307 }
308
309
310
311
312
313 static dbus_bool_t addWatch(DBusWatch *watch, void *data)
314 {
315    dbus_bool_t result = FALSE;
316
317    if (ARRAY_SIZE(gPollInfo.fds)>gPollInfo.nfds)
318    {
319       int flags = dbus_watch_get_flags(watch);
320
321       tObjectEntry * const pEntry = &gPollInfo.objects[gPollInfo.nfds];
322       pEntry->objtype = OT_WATCH;
323       pEntry->watch = watch;
324
325       gPollInfo.fds[gPollInfo.nfds].fd = dbus_watch_get_unix_fd(watch);
326
327       if (TRUE==dbus_watch_get_enabled(watch))
328       {
329          if (flags&DBUS_WATCH_READABLE)
330          {
331             gPollInfo.fds[gPollInfo.nfds].events |= POLLIN;
332          }
333          if (flags&DBUS_WATCH_WRITABLE)
334          {
335             gPollInfo.fds[gPollInfo.nfds].events |= POLLOUT;
336          }
337
338          ++gPollInfo.nfds;
339       }
340
341       result = TRUE;
342    }
343
344    return result;
345 }
346
347
348
349 static void removeWatch(DBusWatch *watch, void *data)
350 {
351    void* w_data = dbus_watch_get_data(watch);
352
353    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("removeWatch called "), DLT_INT( (int)watch) );
354
355    if(w_data)
356       free(w_data);
357
358    dbus_watch_set_data(watch, NULL, NULL);
359 }
360
361
362
363 static void watchToggled(DBusWatch *watch, void *data)
364 {
365    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("watchToggled called "), DLT_INT( (int)watch) );
366
367    if(dbus_watch_get_enabled(watch))
368       addWatch(watch, data);
369    else
370       removeWatch(watch, data);
371 }
372
373
374
375 static dbus_bool_t addTimeout(DBusTimeout *timeout, void *data)
376 {
377    dbus_bool_t ret = FALSE;
378
379    if (ARRAY_SIZE(gPollInfo.fds)>gPollInfo.nfds)
380    {
381       const int interval = dbus_timeout_get_interval(timeout);
382       if ((0<interval)&&(TRUE==dbus_timeout_get_enabled(timeout)))
383       {
384          const int tfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
385          if (-1!=tfd)
386          {
387             const struct itimerspec its = { .it_value= {interval/1000, interval%1000} };
388             if (-1!=timerfd_settime(tfd, 0, &its, NULL))
389             {
390                tObjectEntry * const pEntry = &gPollInfo.objects[gPollInfo.nfds];
391                pEntry->objtype = OT_TIMEOUT;
392                pEntry->timeout = timeout;
393                gPollInfo.fds[gPollInfo.nfds].fd = tfd;
394                gPollInfo.fds[gPollInfo.nfds].events |= POLLIN;
395                ++gPollInfo.nfds;
396                ret = TRUE;
397             }
398             else
399             {
400                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("addTimeout => timerfd_settime() failed"), DLT_STRING(strerror(errno)) );
401             }
402          }
403          else
404          {
405             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("addTimeout => timerfd_create() failed"), DLT_STRING(strerror(errno)) );
406          }
407       }
408    }
409    else
410    {
411       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("addTimeout => cannot create another fd to be poll()'ed"));
412    }
413
414    return ret;
415 }
416
417
418
419 static void removeTimeout(DBusTimeout *timeout, void *data)
420 {
421
422    int i = gPollInfo.nfds;
423    while ((0<i--)&&(timeout!=gPollInfo.objects[i].timeout));
424
425    if (0<i)
426    {
427       if (-1==close(gPollInfo.fds[i].fd))
428       {
429          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("removeTimeout => close() timerfd"), DLT_STRING(strerror(errno)) );
430       }
431
432       --gPollInfo.nfds;
433       while (gPollInfo.nfds>i)
434       {
435          gPollInfo.fds[i] = gPollInfo.fds[i+1];
436          gPollInfo.objects[i] = gPollInfo.objects[i+1];
437          ++i;
438       }
439
440       gPollInfo.fds[gPollInfo.nfds].fd = -1;
441       gPollInfo.objects[gPollInfo.nfds].objtype = OT_NONE;
442    }
443 }
444
445
446
447 /** callback for libdbus' when timeout changed */
448 static void timeoutToggled(DBusTimeout *timeout, void *data)
449 {
450    int i = gPollInfo.nfds;
451    while ((0<i--)&&(timeout!=gPollInfo.objects[i].timeout));
452    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("timeoutToggled") );
453    if (0<i)
454    {
455       const int interval = (TRUE==dbus_timeout_get_enabled(timeout))?dbus_timeout_get_interval(timeout):0;
456       const struct itimerspec its = { .it_value= {interval/1000, interval%1000} };
457       if (-1!=timerfd_settime(gPollInfo.fds[i].fd, 0, &its, NULL))
458       {
459          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("timeoutToggled => timerfd_settime()"), DLT_STRING(strerror(errno)) );
460       }
461    }
462 }
463
464
465
466 int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2,
467              DBusObjectPathVTable vtableFallback, void* userData)
468 {
469    DBusError err;
470    // lock mutex to make sure dbus main loop is running
471    pthread_mutex_lock(&gDbusInitializedMtx);
472
473    DBusConnection* conn = (DBusConnection*)userData;
474    dbus_error_init(&err);
475
476    if (dbus_error_is_set(&err))
477    {
478       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => Connection Error:"), DLT_STRING(err.message) );
479       dbus_error_free(&err);
480    }
481    else if (NULL != conn)
482    {
483       dbus_connection_set_exit_on_disconnect(conn, FALSE);
484       if (-1 == (gEfds = eventfd(0, 0)))
485       {
486          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => eventfd() failed w/ errno:"), DLT_INT(errno) );
487       }
488       else
489       {
490          int ret;
491          memset(&gPollInfo, 0 , sizeof(gPollInfo));
492
493          gPollInfo.nfds = 1;
494          gPollInfo.fds[0].fd = gEfds;
495          gPollInfo.fds[0].events = POLLIN;
496
497          dbus_bus_add_match(conn, "type='signal',interface='org.genivi.persistence.admin',member='PersistenceModeChanged',path='/org/genivi/persistence/admin'", &err);
498
499          // register for messages
500          if (   (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/persistence/adminconsumer", &vtable, userData))
501              && (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/NodeStateManager/LifeCycleConsumer", &vtable2, userData))
502              && (TRUE==dbus_connection_register_fallback(conn, "/", &vtableFallback, userData)) )
503          {
504             if(   (TRUE!=dbus_connection_set_watch_functions(conn, addWatch, removeWatch, watchToggled, NULL, NULL))
505                || (TRUE!=dbus_connection_set_timeout_functions(conn, addTimeout, removeTimeout, timeoutToggled, NULL, NULL)) )
506             {
507                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => dbus_connection_set_watch_functions() failed"));
508             }
509             else
510             {
511                pthread_cond_signal(&gDbusInitializedCond);
512                pthread_mutex_unlock(&gDbusInitializedMtx);
513                do
514                {
515                   bContinue = 0; /* assume error */
516
517                   while (DBUS_DISPATCH_DATA_REMAINS==dbus_connection_dispatch(conn));
518
519                   while ((-1==(ret=poll(gPollInfo.fds, gPollInfo.nfds, -1)))&&(EINTR==errno));
520
521                   if (0>ret)
522                   {
523                      DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => poll() failed w/ errno "), DLT_INT(errno) );
524                   }
525                   else if (0==ret)
526                   {
527                      /* poll time-out */
528                   }
529                   else
530                   {
531                      int i;
532
533                      for (i=0; gPollInfo.nfds>i; ++i)
534                      {
535                         /* anything to do */
536                         if (0!=gPollInfo.fds[i].revents)
537                         {
538                            if (OT_TIMEOUT==gPollInfo.objects[i].objtype)
539                            {
540                               /* time-out occured */
541                               unsigned long long nExpCount = 0;
542                               if ((ssize_t)sizeof(nExpCount)!=read(gPollInfo.fds[i].fd, &nExpCount, sizeof(nExpCount)))
543                               {
544                                  DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => read failed"));
545                               }
546                               DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => timeout"));
547
548                               if (FALSE==dbus_timeout_handle(gPollInfo.objects[i].timeout))
549                               {
550                                  DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => dbus_timeout_handle() failed!?"));
551                               }
552                               bContinue = TRUE;
553                            }
554                            else if (gPollInfo.fds[i].fd == gEfds)
555                            {
556                               /* internal command */
557                               if (0!=(gPollInfo.fds[i].revents & POLLIN))
558                               {
559                                  uint16_t buf[64];
560                                  bContinue = TRUE;
561                                  while ((-1==(ret = read(gPollInfo.fds[i].fd, buf, 64)))&&(EINTR == errno));
562                                  if (0>ret)
563                                  {
564                                     DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => read() failed"), DLT_STRING(strerror(errno)) );
565                                  }
566                                  else if (ret != -1)
567                                  {
568                                     switch (buf[0])
569                                     {
570                                        case CMD_PAS_BLOCK_AND_WRITE_BACK:
571                                           process_block_and_write_data_back((buf[2]), buf[1]);
572                                           break;
573                                        case CMD_LC_PREPARE_SHUTDOWN:
574                                           process_prepare_shutdown((buf[2]), buf[1]);
575                                           break;
576                                        case CMD_SEND_NOTIFY_SIGNAL:
577                                           process_send_notification_signal(conn);
578                                           break;
579                                        case CMD_REG_NOTIFY_SIGNAL:
580                                           process_reg_notification_signal(conn);
581                                           break;
582                                        case CMD_SEND_PAS_REQUEST:
583                                           process_send_pas_request(conn, (buf[2]), buf[1]);
584                                           break;
585                                        case CMD_SEND_PAS_REGISTER:
586                                           process_send_pas_register(conn, (buf[1]), buf[2]);
587                                           break;
588                                        case CMD_SEND_LC_REQUEST:
589                                           process_send_lifecycle_request(conn, (buf[2]), buf[1]);
590                                           break;
591                                        case CMD_SEND_LC_REGISTER:
592                                           process_send_lifecycle_register(conn, (buf[1]), buf[2]);
593                                           break;
594                                        case CMD_QUIT:
595                                           bContinue = FALSE;
596                                           break;
597                                        default:
598                                           DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("mainLoop => command not handled"), DLT_INT(buf[0]) );
599                                           break;
600                                     }
601                                     pthread_mutex_unlock(&gMainLoopMtx);
602                                  }
603                               }
604                            }
605                            else
606                            {
607                               int flags = 0;
608                               if (0!=(gPollInfo.fds[i].revents & POLLIN))
609                               {
610                                  flags |= DBUS_WATCH_READABLE;
611                               }
612                               if (0!=(gPollInfo.fds[i].revents & POLLOUT))
613                               {
614                                  flags |= DBUS_WATCH_WRITABLE;
615                               }
616                               if (0!=(gPollInfo.fds[i].revents & POLLERR))
617                               {
618                                  flags |= DBUS_WATCH_ERROR;
619                               }
620                               if (0!=(gPollInfo.fds[i].revents & POLLHUP))
621                               {
622                                  flags |= DBUS_WATCH_HANGUP;
623                               }
624
625                               bContinue = dbus_watch_handle(gPollInfo.objects[i].watch, flags);
626                            }
627                         }
628                      }
629                   }
630                }
631                while (0!=bContinue);
632             }
633             dbus_connection_unregister_object_path(conn, "/org/genivi/persistence/adminconsumer");
634             dbus_connection_unregister_object_path(conn, "/org/genivi/NodeStateManager/LifeCycleConsumer");
635             dbus_connection_unregister_object_path(conn, "/");
636          }
637          close(gEfds);
638       }
639       dbus_connection_close(conn);
640       dbus_connection_unref(conn);
641       dbus_shutdown();
642    }
643
644    pthread_cond_signal(&gDbusInitializedCond);
645    pthread_mutex_unlock(&gDbusInitializedMtx);
646    return 0;
647 }
648
649
650
651 int deliverToMainloop(tCmd mainloopCmd, unsigned int param1, unsigned int param2)
652 {
653    int rval = 0;
654    uint64_t cmd;
655    uint16_t* cmd_chk;
656
657    pthread_mutex_lock(&gMainLoopMtx);
658
659    cmd = ( ((uint64_t)param2 << 32) | ((uint64_t)param1 << 16) | mainloopCmd);
660
661    if(-1 == write(gEfds, &cmd, (sizeof(uint64_t))))
662    {
663      DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("deliverToMainloop => failed to write to pipe"), DLT_INT(errno));
664      rval = -1;
665    }
666
667    return rval;
668 }
669