Fix for bug 78: AmNodeStateCommunicatorTest throws a runtime exception
[profile/ivi/genivi/genivi-audio-manager.git] / AudioManagerDaemon / src / CAmNodeStateCommunicator.cpp
1 /**
2  * Copyright (C) 2012, BMW AG
3  *
4  * This file is part of GENIVI Project AudioManager.
5  *
6  * Contributions are licensed to the GENIVI Alliance under one or more
7  * Contribution License Agreements.
8  *
9  * \copyright
10  * This Source Code Form is subject to the terms of the
11  * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed with
12  * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
13  *
14  *
15  * \author Christian Linke, christian.linke@bmw.de BMW 2012
16  *
17  * \file CAmNodeStateCommunicator.cpp
18  * For further information see http://www.genivi.org/.
19  *
20  */
21
22 #include "CAmNodeStateCommunicator.h"
23 #include <assert.h>
24 #include <string>
25 #include <fstream>
26 #include <stdexcept>
27 #include "CAmControlSender.h"
28 #include "shared/CAmDltWrapper.h"
29 #include "config.h"
30 #include <sstream>
31
32 namespace am
33 {
34
35 static DBusObjectPathVTable gObjectPathVTable;
36
37 CAmNodeStateCommunicator::CAmNodeStateCommunicator(CAmDbusWrapper* iDbusWrapper) :
38         mpDbusWrapper(iDbusWrapper), //
39         mpControlSender(NULL), //
40         mpDBusConnection(NULL)
41 {
42     assert(mpDbusWrapper);
43     logInfo("CAmNodeStateCommunicator::CAmNodeStateCommunicator started");
44
45     //save the DBusConnection
46     mpDbusWrapper->getDBusConnection(mpDBusConnection);
47     assert(mpDBusConnection!=NULL);
48
49     //register the path and the callback for receiving messages
50     std::string path("LifeCycleConsumer");
51     gObjectPathVTable.message_function=CAmNodeStateCommunicator::receiveCallback;
52     mpDbusWrapper->registerCallback(&gObjectPathVTable, path, this);
53
54     //now we need to make sure we catch the signals from the NSM:
55     dbus_bus_add_match(mpDBusConnection, "type=\'signal\',path=\'/org/genivi/NodeStateManager\'", NULL);
56     if (!dbus_connection_add_filter(mpDBusConnection, CAmNodeStateCommunicator::signalCallback, this, NULL))
57     {
58         logError("CAmNodeStateCommunicator::CAmNodeStateCommunicator not enought memory!");
59         throw std::runtime_error("CAmNodeStateCommunicator::CAmNodeStateCommunicator not enought memory!");
60     }
61     dbus_connection_flush(mpDBusConnection);
62 }
63
64 CAmNodeStateCommunicator::~CAmNodeStateCommunicator()
65 {}
66
67 /** retrieves the actual restartReason
68  *
69  * @param restartReason
70  * @return E_OK on success
71  */
72 am_Error_e CAmNodeStateCommunicator::nsmGetRestartReasonProperty(NsmRestartReason_e& restartReason)
73 {
74     int32_t answer(0);
75     am_Error_e error=readIntegerProperty("RestartReason",answer);
76     restartReason=static_cast<NsmRestartReason_e>(answer);
77     return(error);
78 }
79
80 /** retrieves the actual shutdownreason
81  *
82  * @param ShutdownReason
83  * @return E_OK on success
84  */
85 am_Error_e CAmNodeStateCommunicator::nsmGetShutdownReasonProperty(NsmShutdownReason_e& ShutdownReason)
86 {
87     int32_t answer(0);
88     am_Error_e error=readIntegerProperty("ShutdownReason",answer);
89     ShutdownReason=static_cast<NsmShutdownReason_e>(answer);
90     return(error);
91 }
92
93 /** retrieves the actual runnuing reason
94  *
95  * @param nsmRunningReason
96  * @return E_OK on success
97  */
98 am_Error_e CAmNodeStateCommunicator::nsmGetRunningReasonProperty(NsmRunningReason_e& nsmRunningReason)
99 {
100     int32_t answer(0);
101     am_Error_e error=readIntegerProperty("WakeUpReason",answer);
102     nsmRunningReason=static_cast<NsmRunningReason_e>(answer);
103     return(error);
104 }
105
106 /** gets the node state
107  *
108  * @param nsmNodeState
109  * @return NsmErrorStatus_Ok on success
110  */
111 NsmErrorStatus_e CAmNodeStateCommunicator::nsmGetNodeState(NsmNodeState_e& nsmNodeState)
112 {
113     DBusError error;
114     dbus_error_init(&error);
115
116     uint32_t nodeStateID;
117     uint32_t returnedError;
118
119     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetNodeState");
120
121     if (!message)
122     {
123         logError("CAmNodeStateCommunicator::nsmGetNodeState dbus error:", error.message);
124         return (NsmErrorStatus_Dbus);
125     }
126
127     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
128     if (!reply)
129     {
130         logError("CAmNodeStateCommunicator::nsmGetNodeState failed, dbus error", error.message);
131         return (NsmErrorStatus_Dbus);
132     }
133
134     if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &nodeStateID, DBUS_TYPE_INT32, &returnedError, DBUS_TYPE_INVALID))
135         return (NsmErrorStatus_Dbus);
136
137     dbus_message_unref(reply);
138
139     nsmNodeState=static_cast<NsmNodeState_e>(nodeStateID);
140     return (static_cast<NsmErrorStatus_e>(returnedError));
141 }
142
143 /** gets the session state for a session and seatID
144  *
145  * @param sessionName the name of the session
146  * @param seatID the seatID
147  * @param sessionState
148  * @return NsmErrorStatus_Ok on success
149  */
150 NsmErrorStatus_e CAmNodeStateCommunicator::nsmGetSessionState(const std::string& sessionName, const NsmSeat_e& seatID, NsmSessionState_e& sessionState)
151 {
152     DBusError error;
153     dbus_error_init(&error);
154     DBusMessageIter iter;
155
156     uint32_t returnedError;
157     int32_t BsessionState(0);
158
159     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetSessionState");
160
161     if (!message)
162     {
163         logError("CAmNodeStateCommunicator::nsmGetSessionState dbus error:", error.message);
164         return (NsmErrorStatus_Dbus);
165     }
166
167     dbus_message_iter_init_append(message, &iter);
168
169     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &sessionName))
170     {
171         logError( "CAmNodeStateCommunicator::nsmGetSessionState no more memory");
172         return (NsmErrorStatus_Dbus);
173     }
174
175     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &seatID))
176     {
177         logError( "CAmNodeStateCommunicator::nsmGetSessionState no more memory");
178         return (NsmErrorStatus_Dbus);
179     }
180
181     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
182     if (!reply)
183     {
184         logError("CAmNodeStateCommunicator::nsmGetSessionState failed, dbus error", error.message);
185         return (NsmErrorStatus_Dbus);
186     }
187
188     if(!dbus_message_get_args(reply, &error,
189             DBUS_TYPE_INT32, &BsessionState,
190             DBUS_TYPE_INT32, &returnedError,DBUS_TYPE_INVALID))
191         return (NsmErrorStatus_Dbus);
192
193     dbus_message_unref(reply);
194
195     sessionState=static_cast<NsmSessionState_e>(BsessionState);
196     return (static_cast<NsmErrorStatus_e>(returnedError));
197 }
198
199 /** gets the application mode
200  *
201  * @param applicationMode
202  * @return NsmErrorStatus_Ok on success
203  */
204 NsmErrorStatus_e CAmNodeStateCommunicator::nsmGetApplicationMode(NsmApplicationMode_e& applicationMode)
205 {
206     DBusError error;
207     dbus_error_init(&error);
208
209     uint32_t BapplicationMode(0),returnedError(0);
210
211     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetApplicationMode");
212
213     if (!message)
214     {
215         logError("CAmNodeStateCommunicator::nsmGetApplicationMode dbus error:", error.message);
216         return (NsmErrorStatus_Dbus);
217     }
218
219     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
220     if (!reply)
221     {
222         logError("CAmNodeStateCommunicator::nsmGetApplicationMode failed, dbus error", error.message);
223         return (NsmErrorStatus_Dbus);
224     }
225
226     if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &BapplicationMode, DBUS_TYPE_INT32, &returnedError, DBUS_TYPE_INVALID))
227         return (NsmErrorStatus_Dbus);
228
229     dbus_message_unref(reply);
230
231     applicationMode=static_cast<NsmApplicationMode_e>(BapplicationMode);
232     return (static_cast<NsmErrorStatus_e>(returnedError));
233 }
234
235 /** this function registers the AudioManager as shutdown client at the NSM
236  *  for more information check the Nodestatemanager
237  * @param shutdownMode the shutdownmode you wish to set
238  * @param timeoutMs the timeout you need to have
239  * @return NsmErrorStatus_Ok on success
240  */
241 NsmErrorStatus_e CAmNodeStateCommunicator::nsmRegisterShutdownClient(const uint32_t shutdownMode, const uint32_t timeoutMs)
242 {
243     DBusError error;
244     DBusMessageIter iter;
245     dbus_error_init(&error);
246     int32_t returnError(0);
247     std::string path = std::string(DBUS_SERVICE_OBJECT_PATH) + "/LifeCycleConsumer";
248     const char* charPath = path.c_str();
249     const char* service =DBUS_SERVICE_PREFIX;
250     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "RegisterShutdownClient");
251
252     if (!message)
253     {
254         logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient dbus error:", error.message);
255         return (NsmErrorStatus_Dbus);
256     }
257     dbus_message_iter_init_append(message, &iter);
258
259     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &service))
260     {
261         logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory");
262         return (NsmErrorStatus_Dbus);
263     }
264
265     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &charPath))
266     {
267         logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory");
268         return (NsmErrorStatus_Dbus);
269     }
270
271     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &shutdownMode))
272     {
273         logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory");
274         return (NsmErrorStatus_Dbus);
275     }
276
277     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &timeoutMs))
278     {
279         logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory");
280         return (NsmErrorStatus_Dbus);
281     }
282
283     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
284     dbus_message_unref(message);
285
286     if (!reply)
287     {
288         logError( "CAmRoutingDbusSend::send failed, dbus error", error.message);
289         return (NsmErrorStatus_Dbus);
290     }
291
292     if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &returnError,DBUS_TYPE_INVALID))
293     {
294         logError( "CAmRoutingDbusSend::send failed, dbus error", error.message);
295         return (NsmErrorStatus_Dbus);
296     }
297     dbus_message_unref(reply);
298
299     return (static_cast<NsmErrorStatus_e>(returnError));
300
301 }
302
303 /** this function unregisters the AudioManager as shutdown client at the NSM
304  *
305  * @param shutdownMode
306  * @return NsmErrorStatus_Ok on success
307  */
308 NsmErrorStatus_e CAmNodeStateCommunicator::nsmUnRegisterShutdownClient(const uint32_t shutdownMode)
309 {
310     DBusError error;
311     DBusMessageIter iter;
312     dbus_error_init(&error);
313     int32_t returnError(0);
314     std::string path = std::string(DBUS_SERVICE_OBJECT_PATH) + "/LifeCycleConsumer";
315     const char* charPath = path.c_str();
316     const char* service =DBUS_SERVICE_PREFIX;
317     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "UnRegisterShutdownClient");
318
319     if (!message)
320     {
321         logError( "CAmNodeStateCommunicator::nsmUnRegisterShutdownClient dbus error:", error.message);
322         return (NsmErrorStatus_Dbus);
323     }
324     dbus_message_iter_init_append(message, &iter);
325
326     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &service))
327     {
328         logError( "CAmNodeStateCommunicator::nsmUnRegisterShutdownClient no more memory");
329         return (NsmErrorStatus_Dbus);
330     }
331
332     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &charPath))
333     {
334         logError( "CAmNodeStateCommunicator::nsmUnRegisterShutdownClient no more memory");
335         return (NsmErrorStatus_Dbus);
336     }
337
338     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &shutdownMode))
339     {
340         logError( "CAmNodeStateCommunicator::nsmUnRegisterShutdownClient no more memory");
341         return (NsmErrorStatus_Dbus);
342     }
343
344     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
345     dbus_message_unref(message);
346
347     if (!reply)
348     {
349         logError( "CAmNodeStateCommunicator::nsmUnRegisterShutdownClient failed, dbus error", error.message);
350         return (NsmErrorStatus_Dbus);
351     }
352
353     if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &returnError, DBUS_TYPE_INVALID))
354     {
355         logError( "CAmNodeStateCommunicator::nsmUnRegisterShutdownClient failed, dbus error", error.message);
356         return (NsmErrorStatus_Dbus);
357     }
358     dbus_message_unref(reply);
359
360     return (static_cast<NsmErrorStatus_e>(returnError));
361 }
362
363 /** returns the interface version
364  *
365  * @param version
366  * @return E_OK on success
367  */
368 am_Error_e CAmNodeStateCommunicator::nsmGetInterfaceVersion(uint32_t& version)
369 {
370     DBusError error;
371     dbus_error_init(&error);
372
373     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetInterfaceVersion");
374
375     if (!message)
376     {
377         logError("CAmNodeStateCommunicator::nsmGetInterfaceVersion dbus error:", error.message);
378         return (E_UNKNOWN);
379     }
380
381     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
382
383     dbus_message_unref(message);
384
385     if (!reply)
386     {
387         logError("CAmNodeStateCommunicator::nsmGetInterfaceVersion failed, dbus error", error.message);
388         return (E_UNKNOWN);
389     }
390
391     if(!dbus_message_get_args(reply, &error, DBUS_TYPE_UINT32, &version, DBUS_TYPE_INVALID))
392     {
393         logError("CAmNodeStateCommunicator::nsmGetInterfaceVersion failed, dbus error", error.message);
394         return (E_UNKNOWN);
395     }
396
397     dbus_message_unref(reply);
398
399     return (E_OK);
400 }
401
402 /** sends out the Lifecycle request complete message
403  *
404  * @param RequestId
405  * @param status
406  * @return NsmErrorStatus_Ok on success
407  */
408 NsmErrorStatus_e CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete(const uint32_t RequestId, const NsmErrorStatus_e status)
409 {
410     DBusError error;
411     DBusMessageIter iter;
412     dbus_error_init(&error);
413     int32_t returnError(0);
414     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "LifecycleRequestComplete");
415
416     if (!message)
417     {
418         logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete dbus error:", error.message);
419         return (NsmErrorStatus_Dbus);
420     }
421     dbus_message_iter_init_append(message, &iter);
422
423     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &RequestId))
424     {
425         logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete no more memory");
426         return (NsmErrorStatus_Dbus);
427     }
428
429     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32,&status))
430     {
431         logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete no more memory");
432         return (NsmErrorStatus_Dbus);
433     }
434
435     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
436     dbus_message_unref(message);
437
438     if (!reply)
439     {
440         logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete failed, dbus error", error.message);
441         return (NsmErrorStatus_Dbus);
442     }
443
444     if(!dbus_message_get_args(reply, &error,DBUS_TYPE_INT32, &returnError, DBUS_TYPE_INVALID))
445     {
446         logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete failed, dbus error", error.message);
447         return (NsmErrorStatus_Dbus);
448     }
449     dbus_message_unref(reply);
450
451     return (static_cast<NsmErrorStatus_e>(returnError));
452 }
453
454 void CAmNodeStateCommunicator::registerControlSender(CAmControlSender* iControlSender)
455 {
456     assert(iControlSender);
457     mpControlSender=iControlSender;
458 }
459
460 DBusHandlerResult CAmNodeStateCommunicator::receiveCallback(DBusConnection* conn, DBusMessage* msg, void* user_data)
461 {
462     CAmNodeStateCommunicator* instance = static_cast<CAmNodeStateCommunicator*>(user_data);
463     assert(instance);
464     return (instance->receiveCallbackDelegate(conn,msg));
465 }
466
467 DBusHandlerResult CAmNodeStateCommunicator::receiveCallbackDelegate(DBusConnection* conn, DBusMessage* msg)
468 {
469     if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
470     {
471         sendIntrospection(conn, msg);
472         return (DBUS_HANDLER_RESULT_HANDLED);
473     }
474     else
475     {
476         DBusMessage * returnMessage;
477         dbus_uint32_t Request(0),RequestId(0);
478         //no introspection - ok. So we are only interested in out LifecycleRequest message...
479         std::string method(dbus_message_get_member(msg));
480         if (method=="LifecycleRequest")
481         {
482             DBusMessageIter iter,replyIter;
483             if (!dbus_message_iter_init(msg, &iter))
484             {
485                 logError("CAmNodeStateCommunicator::receiveCallbackDelegate DBus Message has no arguments!");
486                 returnMessage = dbus_message_new_error(msg,DBUS_ERROR_INVALID_ARGS, "DBUS Message has no arguments!");
487                 sendMessage(returnMessage,msg);
488                 return (DBUS_HANDLER_RESULT_HANDLED);
489             }
490
491             if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_UINT32)
492             {
493                 logError("CAmNodeStateCommunicator::receiveCallbackDelegate DBus Message has invalid arguments!");
494                 returnMessage = dbus_message_new_error(msg,DBUS_ERROR_INVALID_ARGS,"DBus argument is not uint32_t!");
495                 sendMessage(returnMessage,msg);
496                 return (DBUS_HANDLER_RESULT_HANDLED);
497             }
498
499             dbus_message_iter_get_basic(&iter, &Request);
500             dbus_message_iter_next(&iter);
501
502             if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_UINT32)
503             {
504                 logError("CAmNodeStateCommunicator::receiveCallbackDelegate DBus Message has invalid arguments!");
505                 returnMessage = dbus_message_new_error(msg,DBUS_ERROR_INVALID_ARGS,"DBus argument is not uint32_t!");
506                 sendMessage(returnMessage,msg);
507                 return (DBUS_HANDLER_RESULT_HANDLED);
508             }
509
510             dbus_message_iter_get_basic(&iter, &RequestId);
511
512             assert(mpControlSender);
513             NsmErrorStatus_e returnError = mpControlSender->hookSystemLifecycleRequest(static_cast<uint32_t>(Request),static_cast<uint32_t>(RequestId));
514
515             returnMessage = dbus_message_new_method_return(msg);
516
517             if (returnMessage == NULL)
518             {
519                 logError("CAmNodeStateCommunicator::receiveCallbackDelegate Cannot allocate DBus message!");
520                 returnMessage = dbus_message_new_error(msg,DBUS_ERROR_NO_MEMORY,"Cannot create reply!");
521                 sendMessage(returnMessage,msg);
522                 return (DBUS_HANDLER_RESULT_HANDLED);
523             }
524
525             dbus_message_iter_init_append(returnMessage, &replyIter);
526
527             if (!dbus_message_iter_append_basic(&replyIter, DBUS_TYPE_INT32, &returnError))
528             {
529                 logError("CAmNodeStateCommunicator::receiveCallbackDelegate Cannot allocate DBus message!");
530                 returnMessage = dbus_message_new_error(msg,DBUS_ERROR_NO_MEMORY,"Cannot create reply!");
531             }
532             sendMessage(returnMessage,msg);
533             return (DBUS_HANDLER_RESULT_HANDLED);
534         }
535     }
536     return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
537 }
538
539 void CAmNodeStateCommunicator::sendIntrospection(DBusConnection* conn, DBusMessage* msg)
540 {
541     assert(conn != NULL);
542     assert(msg != NULL);
543     DBusMessage* reply;
544     DBusMessageIter args;
545     dbus_uint32_t serial = 0;
546
547     // create a reply from the message
548     reply = dbus_message_new_method_return(msg);
549     std::string fullpath(NSM_INTROSPECTION_FILE);
550     std::ifstream in(fullpath.c_str(), std::ifstream::in);
551     if (!in)
552     {
553        logError("IAmCommandReceiverShadow::sendIntrospection could not load xml file ",fullpath);
554        throw std::runtime_error("IAmCommandReceiverShadow::sendIntrospection Could not load introspecton XML");
555     }
556     std::stringstream buffer;
557     buffer << in.rdbuf();
558     std::string introspect = buffer.str();
559     const char* string = introspect.c_str();
560
561     // add the arguments to the reply
562     dbus_message_iter_init_append(reply, &args);
563     if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string))
564     {
565        logError( "CAmNodeStateCommunicator::sendIntrospection DBUS handler Out Of Memory!");
566     }
567
568     // send the reply && flush the connection
569     if (!dbus_connection_send(conn, reply, &serial))
570     {
571         logError( "CAmNodeStateCommunicator::sendIntrospection DBUS handler Out Of Memory!");
572     }
573     dbus_connection_flush(conn);
574
575     // free the reply
576     dbus_message_unref(reply);
577 }
578
579 void CAmNodeStateCommunicator::sendMessage(DBusMessage* message, DBusMessage* origMessage)
580 {
581     dbus_uint32_t serial = dbus_message_get_serial(origMessage);
582
583     if(!dbus_connection_send(mpDBusConnection, message, &serial))
584     {
585         logError( "CAmNodeStateCommunicator::sendMessage DBUS handler Out Of Memory!");
586     }
587     dbus_connection_flush(mpDBusConnection);
588     dbus_message_unref(message);
589 }
590
591 DBusHandlerResult CAmNodeStateCommunicator::signalCallback(DBusConnection* conn, DBusMessage* msg, void* user_data)
592 {
593     (void) conn;
594     CAmNodeStateCommunicator* instance(static_cast<CAmNodeStateCommunicator*>(user_data));
595
596     const char* iface = dbus_message_get_interface(msg);
597     if (iface==NULL)
598         return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
599     std::string interface(iface);
600     std::string member = dbus_message_get_member(msg);
601
602     if (interface=="org.genivi.NodeStateManager.Consumer")
603     {
604         if (member=="NodeState")
605         {
606             int32_t nodeState;
607             DBusMessageIter iter;
608             if (!dbus_message_iter_init(msg, &iter))
609             {
610                 logError("CAmNodeStateCommunicator::signalCallback NodeState DBus Message has no arguments!");
611                 return (DBUS_HANDLER_RESULT_HANDLED);
612             }
613
614             if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32)
615             {
616                 logError("CAmNodeStateCommunicator::signalCallback NodeState DBus Message has invalid arguments!");
617                 return (DBUS_HANDLER_RESULT_HANDLED);
618             }
619
620             dbus_message_iter_get_basic(&iter, &nodeState);
621
622             logInfo("CAmNodeStateCommunicator::signalCallback got signal NodeState, with nodeState",nodeState);
623
624             assert(instance->mpControlSender);
625             instance->mpControlSender->hookSystemNodeStateChanged(static_cast<NsmNodeState_e>(nodeState));
626             return (DBUS_HANDLER_RESULT_HANDLED);
627         }
628
629         else if (member=="NodeApplicationMode")
630         {
631             int32_t nodeApplicationMode;
632             DBusMessageIter iter;
633             if (!dbus_message_iter_init(msg, &iter))
634             {
635                 logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has no arguments!");
636                 return (DBUS_HANDLER_RESULT_HANDLED);
637             }
638
639             if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32)
640             {
641                 logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!");
642                 return (DBUS_HANDLER_RESULT_HANDLED);
643             }
644
645             dbus_message_iter_get_basic(&iter, &nodeApplicationMode);
646
647             logInfo("CAmNodeStateCommunicator::signalCallback got signal nodeApplicationMode, with applicationMode",nodeApplicationMode);
648
649             assert(instance->mpControlSender);
650             instance->mpControlSender->hookSystemNodeApplicationModeChanged(static_cast<NsmApplicationMode_e>(nodeApplicationMode));
651             return (DBUS_HANDLER_RESULT_HANDLED);
652         }
653
654         else if (member=="SessionStateChanged")
655         {
656             std::string sessionName;
657             NsmSeat_e seatID;
658             NsmSessionState_e sessionState;
659             DBusMessageIter iter;
660             if (!dbus_message_iter_init(msg, &iter))
661             {
662                 logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has no arguments!");
663                 return (DBUS_HANDLER_RESULT_HANDLED);
664             }
665
666             if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_STRING)
667             {
668                 logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!");
669                 return (DBUS_HANDLER_RESULT_HANDLED);
670             }
671
672             char * sessionNameChar;
673             dbus_message_iter_get_basic(&iter, &sessionNameChar);
674             sessionName=std::string(sessionNameChar);
675             dbus_message_iter_next(&iter);
676
677             if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32)
678             {
679                 logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!");
680                 return (DBUS_HANDLER_RESULT_HANDLED);
681             }
682
683             dbus_message_iter_get_basic(&iter, &seatID);
684             dbus_message_iter_next(&iter);
685
686             if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32)
687             {
688                 logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!");
689                 return (DBUS_HANDLER_RESULT_HANDLED);
690             }
691
692             dbus_message_iter_get_basic(&iter, &sessionState);
693
694
695             logInfo("CAmNodeStateCommunicator::signalCallback got signal sessionStateChanged, with session",sessionName,"seatID=",seatID,"sessionState",sessionState);
696
697             assert(instance->mpControlSender);
698             instance->mpControlSender->hookSystemSessionStateChanged(sessionName,seatID,sessionState);
699             return (DBUS_HANDLER_RESULT_HANDLED);
700         }
701
702         else
703         {
704             return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
705         }
706     }
707
708     return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
709 }
710
711 am_Error_e CAmNodeStateCommunicator::readIntegerProperty(const std::string property, int32_t& value)
712 {
713     DBusError error;
714     dbus_error_init(&error);
715     DBusMessageIter iter,iterVariant;
716
717     DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, "org.freedesktop.DBus.Properties", "Get");
718
719     if (!message)
720     {
721         logError("CAmNodeStateCommunicator::readIntegerProperty dbus error:", error.message);
722         dbus_message_unref(message);
723         return (E_UNKNOWN);
724     }
725
726
727     dbus_message_iter_init_append(message, &iter);
728     const char *interface=NSM_INTERFACE;
729     const char *propertyChar=property.c_str();
730     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface))
731     {
732         logError("CAmNodeStateCommunicator::readIntegerProperty append error");
733         dbus_message_unref(message);
734         return (E_UNKNOWN);
735     }
736
737     if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &propertyChar))
738     {
739         logError("CAmNodeStateCommunicator::readIntegerProperty append error");
740         dbus_message_unref(message);
741         return (E_UNKNOWN);
742     }
743
744     DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error));
745     if (!reply)
746     {
747         logError("CAmNodeStateCommunicator::readIntegerProperty failed, dbus error", error.message);
748         dbus_message_unref(message);
749         return (E_UNKNOWN);
750     }
751
752     if(!dbus_message_iter_init(reply,&iterVariant))
753     {
754         logError("CAmNodeStateCommunicator::readIntegerProperty failed, dbus error", error.message);
755                 dbus_message_unref(message);
756                 dbus_message_unref(reply);
757                 return (E_UNKNOWN);
758     }
759     if (dbus_message_iter_get_arg_type (&iterVariant)!= DBUS_TYPE_VARIANT)
760     {
761         logError("CAmNodeStateCommunicator::readIntegerProperty failed, dbus return type wrong");
762         dbus_message_unref(reply);
763         dbus_message_unref(message);
764         return (E_UNKNOWN);
765     }
766     DBusMessageIter subiter;
767     dbus_message_iter_recurse (&iterVariant, &subiter);
768     if (dbus_message_iter_get_arg_type (&subiter)!= DBUS_TYPE_INT32)
769     {
770         logError("CAmNodeStateCommunicator::readIntegerProperty failed, dbus return type wrong");
771         dbus_message_unref(reply);
772         dbus_message_unref(message);
773         return (E_UNKNOWN);
774     }
775
776    dbus_message_iter_get_basic(&subiter,&value);
777    dbus_message_unref(reply);
778    dbus_message_unref(message);
779
780     return (E_OK);
781 }
782
783 } /* namespace am */