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