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