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