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