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