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