From 54c5e965fe8f9a53a78834028fd65c792493da2b Mon Sep 17 00:00:00 2001 From: christian linke Date: Mon, 17 Dec 2012 16:15:11 +0100 Subject: * added new interfaces & nsm support + nsm tests + fixed some unit tests + fixed rundown Signed-off-by: christian linke --- AudioManagerDaemon/src/CAmCommandReceiver.cpp | 40 +- AudioManagerDaemon/src/CAmCommandSender.cpp | 30 + AudioManagerDaemon/src/CAmControlReceiver.cpp | 171 ++++- AudioManagerDaemon/src/CAmControlSender.cpp | 167 ++++- AudioManagerDaemon/src/CAmDatabaseHandler.cpp | 661 +++++++++++++++++- AudioManagerDaemon/src/CAmDatabaseObserver.cpp | 23 + AudioManagerDaemon/src/CAmDbusWrapper.cpp | 7 +- .../src/CAmNodeStateCommunicator.cpp | 763 +++++++++++++++++++++ AudioManagerDaemon/src/CAmRoutingReceiver.cpp | 97 ++- AudioManagerDaemon/src/CAmRoutingSender.cpp | 72 ++ AudioManagerDaemon/src/CAmSocketHandler.cpp | 17 +- AudioManagerDaemon/src/CAmTelnetMenuHelper.cpp | 1 - AudioManagerDaemon/src/CAmWatchdog.cpp | 1 - AudioManagerDaemon/src/main.cpp | 44 +- 14 files changed, 2034 insertions(+), 60 deletions(-) create mode 100644 AudioManagerDaemon/src/CAmNodeStateCommunicator.cpp (limited to 'AudioManagerDaemon/src') diff --git a/AudioManagerDaemon/src/CAmCommandReceiver.cpp b/AudioManagerDaemon/src/CAmCommandReceiver.cpp index c507d5f..f3fa3ef 100644 --- a/AudioManagerDaemon/src/CAmCommandReceiver.cpp +++ b/AudioManagerDaemon/src/CAmCommandReceiver.cpp @@ -39,7 +39,9 @@ CAmCommandReceiver::CAmCommandReceiver(CAmDatabaseHandler *iDatabaseHandler, CAm mListStartupHandles(), // mListRundownHandles(), // mWaitStartup(false), // - mWaitRundown(false) + mWaitRundown(false), + mLastErrorStartup(E_OK), // + mLastErrorRundown(E_OK) // { assert(mDatabaseHandler!=NULL); @@ -184,18 +186,22 @@ void CAmCommandReceiver::getInterfaceVersion(std::string & version) const version = CommandReceiveVersion; } -void CAmCommandReceiver::confirmCommandReady(const uint16_t handle) +void CAmCommandReceiver::confirmCommandReady(const uint16_t handle, const am_Error_e error) { + if (error !=E_OK) + mLastErrorStartup=error; mListStartupHandles.erase(std::remove(mListStartupHandles.begin(), mListStartupHandles.end(), handle), mListStartupHandles.end()); if (mWaitStartup && mListStartupHandles.empty()) - mControlSender->confirmCommandReady(); + mControlSender->confirmCommandReady(mLastErrorStartup); } -void CAmCommandReceiver::confirmCommandRundown(const uint16_t handle) +void CAmCommandReceiver::confirmCommandRundown(const uint16_t handle, const am_Error_e error) { + if (error !=E_OK) + mLastErrorRundown=error; mListRundownHandles.erase(std::remove(mListRundownHandles.begin(), mListRundownHandles.end(), handle), mListRundownHandles.end()); if (mWaitRundown && mListRundownHandles.empty()) - mControlSender->confirmCommandRundown(); + mControlSender->confirmCommandRundown(mLastErrorRundown); } uint16_t CAmCommandReceiver::getStartupHandle() @@ -215,11 +221,35 @@ uint16_t CAmCommandReceiver::getRundownHandle() void CAmCommandReceiver::waitOnStartup(bool startup) { mWaitStartup = startup; + mLastErrorStartup=E_OK; +} + +am_Error_e CAmCommandReceiver::getListSinkMainNotificationConfigurations(const am_sinkID_t sinkID, std::vector& listMainNotificationConfigurations) const +{ + return (mDatabaseHandler->getListSinkMainNotificationConfigurations(sinkID,listMainNotificationConfigurations)); +} + +am_Error_e CAmCommandReceiver::getListSourceMainNotificationConfigurations(const am_sourceID_t sourceID, std::vector& listMainNotificationConfigurations) const +{ + return (mDatabaseHandler->getListSourceMainNotificationConfigurations(sourceID,listMainNotificationConfigurations)); +} + +am_Error_e CAmCommandReceiver::setSinkMainNotificationConfiguration(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + logInfo("CommandReceiver::setSinkMainNotificationConfiguration got called, sinkID=", sinkID, " notificationType=",mainNotificationConfiguration.notificationType, " parameter=", mainNotificationConfiguration.notificationParameter, "status=",mainNotificationConfiguration.notificationStatus); + return (mControlSender->hookUserSetMainSinkNotificationConfiguration(sinkID,mainNotificationConfiguration)); +} + +am_Error_e CAmCommandReceiver::setSourceMainNotificationConfiguration(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + logInfo("CommandReceiver::setSourceMainNotificationConfiguration got called, sourceID=", sourceID, " notificationType=",mainNotificationConfiguration.notificationType, " parameter=", mainNotificationConfiguration.notificationParameter, "status=",mainNotificationConfiguration.notificationStatus); + return (mControlSender->hookUserSetMainSourceNotificationConfiguration(sourceID,mainNotificationConfiguration)); } void CAmCommandReceiver::waitOnRundown(bool rundown) { mWaitRundown = rundown; + mLastErrorStartup=E_OK; } } diff --git a/AudioManagerDaemon/src/CAmCommandSender.cpp b/AudioManagerDaemon/src/CAmCommandSender.cpp index 1494bc1..7ec2740 100644 --- a/AudioManagerDaemon/src/CAmCommandSender.cpp +++ b/AudioManagerDaemon/src/CAmCommandSender.cpp @@ -297,6 +297,36 @@ am_Error_e am::CAmCommandSender::getListPlugins(std::vector & inter return (E_OK); } +void CAmCommandSender::cbSinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector& listMainSoundProperties) +{ + CALL_ALL_INTERFACES(cbSinkUpdated(sinkID,sinkClassID,listMainSoundProperties)); +} + +void CAmCommandSender::cbSourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector& listMainSoundProperties) +{ + CALL_ALL_INTERFACES(cbSourceUpdated(sourceID,sourceClassID,listMainSoundProperties)); +} + +void CAmCommandSender::cbSinkNotification(const am_sinkID_t sinkID, const am_NotificationPayload_s notification) +{ + CALL_ALL_INTERFACES(cbSinkNotification(sinkID,notification)); +} + +void CAmCommandSender::cbSourceNotification(const am_sourceID_t sourceID, const am_NotificationPayload_s notification) +{ + CALL_ALL_INTERFACES(cbSourceNotification(sourceID,notification)); +} + +void CAmCommandSender::cbSinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + CALL_ALL_INTERFACES(cbSinkMainNotificationConfigurationChanged(sinkID,mainNotificationConfiguration)); +} + +void CAmCommandSender::cbSourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + CALL_ALL_INTERFACES(cbSourceMainNotificationConfigurationChanged(sourceID,mainNotificationConfiguration)); +} + void CAmCommandSender::unloadLibraries(void) { std::vector::iterator iterator = mListLibraryHandles.begin(); diff --git a/AudioManagerDaemon/src/CAmControlReceiver.cpp b/AudioManagerDaemon/src/CAmControlReceiver.cpp index f78a0f3..cfa9467 100644 --- a/AudioManagerDaemon/src/CAmControlReceiver.cpp +++ b/AudioManagerDaemon/src/CAmControlReceiver.cpp @@ -22,22 +22,42 @@ #include "CAmControlReceiver.h" #include #include +#include #include "config.h" #include "CAmDatabaseHandler.h" #include "CAmRoutingSender.h" #include "CAmCommandSender.h" #include "CAmRouter.h" +#include "CAmNodeStateCommunicator.h" #include "shared/CAmDltWrapper.h" #include "shared/CAmSocketHandler.h" + namespace am { +CAmControlReceiver::CAmControlReceiver(CAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmCommandSender *iCommandSender, CAmSocketHandler *iSocketHandler, CAmRouter* iRouter, CAmNodeStateCommunicator* iNodeStateCommunicator) : + mDatabaseHandler(iDatabaseHandler), // + mRoutingSender(iRoutingSender), // + mCommandSender(iCommandSender), // + mSocketHandler(iSocketHandler), // + mRouter(iRouter), // + mNodeStateCommunicator(iNodeStateCommunicator) +{ + assert(mDatabaseHandler!=NULL); + assert(mRoutingSender!=NULL); + assert(mCommandSender!=NULL); + assert(mSocketHandler!=NULL); + assert(mRouter!=NULL); + assert(iNodeStateCommunicator!=NULL); +} + CAmControlReceiver::CAmControlReceiver(CAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmCommandSender *iCommandSender, CAmSocketHandler *iSocketHandler, CAmRouter* iRouter) : mDatabaseHandler(iDatabaseHandler), // mRoutingSender(iRoutingSender), // mCommandSender(iCommandSender), // mSocketHandler(iSocketHandler), // - mRouter(iRouter) + mRouter(iRouter), // + mNodeStateCommunicator(NULL) { assert(mDatabaseHandler!=NULL); assert(mRoutingSender!=NULL); @@ -476,14 +496,26 @@ void CAmControlReceiver::setRoutingReady() mRoutingSender->setRoutingReady(); } -void CAmControlReceiver::confirmControllerReady() +void CAmControlReceiver::confirmControllerReady(const am_Error_e error) { //todo: one time implement here system interaction with NSM + if (error!=E_OK) + logError("CAmControlReceiver::confirmControllerReady controller reported error", error); } -void CAmControlReceiver::confirmControllerRundown() +void CAmControlReceiver::confirmControllerRundown(const am_Error_e error) { - logInfo ("CAmControlReceiver::confirmControllerRundown(), will exit now"); + if (error!=E_OK) + { + logError("CAmControlReceiver::confirmControllerRundown() exited with error ",error); + //we might be blocked here -> so lets better exit right away + throw std::runtime_error("controller Confirmed with error"); + } + + logInfo ("CAmControlReceiver::confirmControllerRundown(), will exit now"); + + //end the mainloop here... + mSocketHandler->exit_mainloop(); } am_Error_e CAmControlReceiver::getSocketHandler(CAmSocketHandler *& socketHandler) @@ -508,5 +540,136 @@ void CAmControlReceiver::getInterfaceVersion(std::string & version) const { version = ControlReceiveVersion; } + +am_Error_e CAmControlReceiver::changeSourceDB(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector listSoundProperties, const std::vector listConnectionFormats, const std::vector listMainSoundProperties) +{ + logInfo("CAmControlReceiver::changeSource was called, sourceID", sourceID); + return (mDatabaseHandler->changeSource(sourceID,sourceClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties)); +} + +am_Error_e CAmControlReceiver::changeSinkDB(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector listSoundProperties, const std::vector listConnectionFormats, const std::vector listMainSoundProperties) +{ + logInfo("CAmControlReceiver::changeSink was called with sinkID", sinkID); + return (mDatabaseHandler->changeSink(sinkID,sinkClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties)); +} + +am_Error_e CAmControlReceiver::changeGatewayDB(const am_gatewayID_t gatewayID, const std::vector listSourceConnectionFormats, const std::vector listSinkConnectionFormats, const std::vector convertionMatrix) +{ + logInfo("CAmControlReceiver::changeGatewayDB was called with gatewayID", gatewayID); + return (mDatabaseHandler->changeGatewayDB(gatewayID,listSourceConnectionFormats,listSinkConnectionFormats,convertionMatrix)); +} + +am_Error_e CAmControlReceiver::setVolumes(am_Handle_s& handle, const std::vector listVolumes) +{ + logInfo("CAmControlReceiver::setVolumes got called"); + return (mRoutingSender->asyncSetVolumes(handle,listVolumes)); +} + +am_Error_e CAmControlReceiver::setSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s notificationConfiguration) +{ + logInfo("CAmControlReceiver::setSinkNotificationConfiguration called, sinkID=",sinkID,"notificationConfiguration.notificationType=",notificationConfiguration.notificationType,"notificationConfiguration.notificationStatus",notificationConfiguration.notificationStatus,"notificationConfiguration.notificationParameter",notificationConfiguration.notificationParameter); + return (mRoutingSender->asyncSetSinkNotificationConfiguration(handle,sinkID,notificationConfiguration)); +} + +am_Error_e CAmControlReceiver::setSourceNotificationConfiguration(am_Handle_s& handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s notificationConfiguration) +{ + logInfo("CAmControlReceiver::setSourceNotificationConfiguration called, sourceID=",sourceID,"notificationConfiguration.notificationType=",notificationConfiguration.notificationType,"notificationConfiguration.notificationStatus",notificationConfiguration.notificationStatus,"notificationConfiguration.notificationParameter",notificationConfiguration.notificationParameter); + return (mRoutingSender->asyncSetSourceNotificationConfiguration(handle,sourceID,notificationConfiguration)); +} + +void CAmControlReceiver::sendSinkMainNotificationPayload(const am_sinkID_t sinkID, const am_NotificationPayload_s notificationPayload) +{ + logInfo("CAmControlReceiver::sendSinkMainNotificationPayload called, sinkID=",sinkID,"type=",notificationPayload.notificationType,"value=",notificationPayload.notificationValue); + mCommandSender->cbSinkNotification(sinkID,notificationPayload); +} + +void CAmControlReceiver::sendSourceMainNotificationPayload(const am_sourceID_t sourceID, const am_NotificationPayload_s notificationPayload) +{ + logInfo("CAmControlReceiver::sendSourceMainNotificationPayload called, sourceID=",sourceID,"type=",notificationPayload.notificationType,"value=",notificationPayload.notificationValue); + mCommandSender->cbSourceNotification(sourceID,notificationPayload); +} + +am_Error_e CAmControlReceiver::changeMainSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + logInfo("CAmControlReceiver::changeMainSinkNotificationConfigurationDB was called with sinkID", sinkID); + return (mDatabaseHandler->changeMainSinkNotificationConfigurationDB(sinkID,mainNotificationConfiguration)); +} + +am_Error_e CAmControlReceiver::changeMainSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + logInfo("CAmControlReceiver::changeMainSourceNotificationConfigurationDB was called with sourceID", sourceID); + return (mDatabaseHandler->changeMainSourceNotificationConfigurationDB(sourceID,mainNotificationConfiguration)); +} + +am_Error_e CAmControlReceiver::nsmGetRestartReasonProperty(NsmRestartReason_e& restartReason) +{ + if (!mNodeStateCommunicator) + return (E_NON_EXISTENT); + return (mNodeStateCommunicator->nsmGetRestartReasonProperty(restartReason)); +} + +am_Error_e CAmControlReceiver::nsmGetShutdownReasonProperty(NsmShutdownReason_e& ShutdownReason) +{ + if (!mNodeStateCommunicator) + return (E_NON_EXISTENT); + return (mNodeStateCommunicator->nsmGetShutdownReasonProperty(ShutdownReason)); +} + +am_Error_e CAmControlReceiver::nsmGetRunningReasonProperty(NsmRunningReason_e& nsmRunningReason) +{ + if (!mNodeStateCommunicator) + return (E_NON_EXISTENT); + return (mNodeStateCommunicator->nsmGetRunningReasonProperty(nsmRunningReason)); +} + +NsmErrorStatus_e CAmControlReceiver::nsmGetNodeState(NsmNodeState_e& nsmNodeState) +{ + if (!mNodeStateCommunicator) + return (NsmErrorStatus_Error); + return (mNodeStateCommunicator->nsmGetNodeState(nsmNodeState)); +} + +NsmErrorStatus_e CAmControlReceiver::nsmGetSessionState(const std::string& sessionName, const NsmSeat_e& seatID, NsmSessionState_e& sessionState) +{ + if (!mNodeStateCommunicator) + return (NsmErrorStatus_Error); + return (mNodeStateCommunicator->nsmGetSessionState(sessionName,seatID,sessionState)); +} + +NsmErrorStatus_e CAmControlReceiver::nsmGetApplicationMode(NsmApplicationMode_e& applicationMode) +{ + if (!mNodeStateCommunicator) + return (NsmErrorStatus_Error); + return (mNodeStateCommunicator->nsmGetApplicationMode(applicationMode)); +} + +NsmErrorStatus_e CAmControlReceiver::nsmRegisterShutdownClient(const uint32_t shutdownMode, const uint32_t timeoutMs) +{ + if (!mNodeStateCommunicator) + return (NsmErrorStatus_Error); + return (mNodeStateCommunicator->nsmRegisterShutdownClient(shutdownMode,timeoutMs)); +} + +NsmErrorStatus_e CAmControlReceiver::nsmUnRegisterShutdownClient(const uint32_t shutdownMode) +{ + if (!mNodeStateCommunicator) + return (NsmErrorStatus_Error); + return (mNodeStateCommunicator->nsmUnRegisterShutdownClient(shutdownMode)); +} + +am_Error_e CAmControlReceiver::nsmGetInterfaceVersion(uint32_t& version) +{ + if (!mNodeStateCommunicator) + return (E_NON_EXISTENT); + return (mNodeStateCommunicator->nsmGetInterfaceVersion(version)); +} + +NsmErrorStatus_e CAmControlReceiver::nsmSendLifecycleRequestComplete(const uint32_t RequestId, const NsmErrorStatus_e status) +{ + if (!mNodeStateCommunicator) + return (NsmErrorStatus_Error); + return (mNodeStateCommunicator->nsmSendLifecycleRequestComplete(RequestId,status)); +} + } diff --git a/AudioManagerDaemon/src/CAmControlSender.cpp b/AudioManagerDaemon/src/CAmControlSender.cpp index 569e4c4..da2321e 100644 --- a/AudioManagerDaemon/src/CAmControlSender.cpp +++ b/AudioManagerDaemon/src/CAmControlSender.cpp @@ -36,14 +36,21 @@ namespace am CAmControlSender* CAmControlSender::mInstance=NULL; -CAmControlSender::CAmControlSender(std::string controlPluginFile) : +CAmControlSender::CAmControlSender(std::string controlPluginFile,CAmSocketHandler* sockethandler) : + receiverCallbackT(this, &CAmControlSender::receiverCallback),// + checkerCallbackT(this, &CAmControlSender::checkerCallback),// + dispatcherCallbackT(this, &CAmControlSender::dispatcherCallback), // + mPipe(), // mlibHandle(NULL), // - mController(NULL) + mController(NULL), // + mSignal(0) { + assert(sockethandler); std::ifstream isfile(controlPluginFile.c_str()); if (!isfile) { logError("ControlSender::ControlSender: Controller plugin not found:", controlPluginFile); + throw std::runtime_error("Could not find controller plugin!"); } else if (!controlPluginFile.empty()) { @@ -70,6 +77,18 @@ CAmControlSender::CAmControlSender(std::string controlPluginFile) : { logError("ControlSender::ControlSender: No controller loaded !"); } + + //here we need a pipe to be able to call the rundown function out of the mainloop + if (pipe(mPipe) == -1) + { + logError("CAmControlSender could not create pipe!"); + } + + //add the pipe to the poll - nothing needs to be proccessed here we just need the pipe to trigger the ppoll + short event = 0; + sh_pollHandle_t handle; + event |= POLLIN; + sockethandler->addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, &dispatcherCallbackT, NULL, handle); } CAmControlSender::~CAmControlSender() @@ -323,10 +342,11 @@ void CAmControlSender::setControllerReady() mController->setControllerReady(); } -void CAmControlSender::setControllerRundown() +void CAmControlSender::setControllerRundown(const int16_t signal) { assert(mController); - mController->setControllerRundown(); + logInfo("CAmControlSender::setControllerRundown received, signal=",signal); + mController->setControllerRundown(signal); } am_Error_e am::CAmControlSender::getConnectionFormatChoice(const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_Route_s listRoute, const std::vector listPossibleConnectionFormats, std::vector & listPrioConnectionFormats) @@ -340,27 +360,150 @@ void CAmControlSender::getInterfaceVersion(std::string & version) const version = ControlSendVersion; } -void CAmControlSender::confirmCommandReady() +void CAmControlSender::confirmCommandReady(const am_Error_e error) +{ + assert(mController); + mController->confirmCommandReady(error); +} + +void CAmControlSender::confirmRoutingReady(const am_Error_e error) +{ + assert(mController); + mController->confirmRoutingReady(error); +} + +void CAmControlSender::confirmCommandRundown(const am_Error_e error) +{ + assert(mController); + mController->confirmCommandRundown(error); +} + +void CAmControlSender::confirmRoutingRundown(const am_Error_e error) +{ + assert(mController); + mController->confirmRoutingRundown(error); +} + +void CAmControlSender::hookSystemNodeStateChanged(const NsmNodeState_e NodeStateId) +{ + assert(mController); + mController->hookSystemNodeStateChanged(NodeStateId); +} + +void CAmControlSender::hookSystemNodeApplicationModeChanged(const NsmApplicationMode_e ApplicationModeId) { assert(mController); - mController->confirmCommandReady(); + mController->hookSystemNodeApplicationModeChanged(ApplicationModeId); } -void CAmControlSender::confirmRoutingReady() +am_Error_e CAmControlSender::hookSystemUpdateSink(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector listSoundProperties, const std::vector listConnectionFormats, std::vector listMainSoundProperties) { assert(mController); - mController->confirmRoutingReady(); + return (mController->hookSystemUpdateSink(sinkID,sinkClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties)); } -void CAmControlSender::confirmCommandRundown() +am_Error_e CAmControlSender::hookSystemUpdateSource(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector listSoundProperties, const std::vector listConnectionFormats, std::vector listMainSoundProperties) { assert(mController); - mController->confirmCommandRundown(); + return (mController->hookSystemUpdateSource(sourceID,sourceClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties)); } -void CAmControlSender::confirmRoutingRundown() +am_Error_e CAmControlSender::hookSystemUpdateGateway(const am_gatewayID_t gatewayID, const std::vector listSourceConnectionFormats, const std::vector listSinkConnectionFromats, const std::vector convertionMatrix) { assert(mController); - mController->confirmRoutingRundown(); + return (mController->hookSystemUpdateGateway(gatewayID,listSourceConnectionFormats,listSinkConnectionFromats,convertionMatrix)); } + +void CAmControlSender::cbAckSetVolume(const am_Handle_s handle, const std::vector listVolumes, const am_Error_e error) +{ + assert(mController); + mController->cbAckSetVolume(handle,listVolumes,error); +} + +void CAmControlSender::cbAckSetSinkNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) +{ + assert(mController); + mController->cbAckSetSinkNotificationConfiguration(handle,error); +} + +void CAmControlSender::cbAckSetSourceNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) +{ + assert(mController); + mController->cbAckSetSourceNotificationConfiguration(handle,error); +} + +void CAmControlSender::hookSinkNotificationDataChanged(const am_sinkID_t sinkID, const am_NotificationPayload_s payload) +{ + assert(mController); + mController->hookSinkNotificationDataChanged(sinkID,payload); +} + +void CAmControlSender::hookSourceNotificationDataChanged(const am_sourceID_t sourceID, const am_NotificationPayload_s payload) +{ + assert(mController); + mController->hookSourceNotificationDataChanged(sourceID,payload); +} + +am_Error_e CAmControlSender::hookUserSetMainSinkNotificationConfiguration(const am_sinkID_t sinkID, const am_NotificationConfiguration_s notificationConfiguration) +{ + assert(mController); + return (mController->hookUserSetMainSinkNotificationConfiguration(sinkID,notificationConfiguration)); +} + +am_Error_e CAmControlSender::hookUserSetMainSourceNotificationConfiguration(const am_sourceID_t sourceID, const am_NotificationConfiguration_s notificationConfiguration) +{ + assert(mController); + return (mController->hookUserSetMainSourceNotificationConfiguration(sourceID,notificationConfiguration)); +} + +void CAmControlSender::receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) +{ + (void) handle; + (void) userData; + //get the signal number from the socket + read(pollfd.fd, &mSignal, sizeof(mSignal)); +} + +bool CAmControlSender::checkerCallback(const sh_pollHandle_t handle, void* userData) +{ + (void) handle; + (void) userData; + return (true); +} + +void CAmControlSender::hookSystemSessionStateChanged(const std::string sessionName, const int32_t seatID, const NsmSessionState_e sessionStateID) +{ + assert(mController); + mController->hookSystemSessionStateChanged(sessionName,seatID,sessionStateID); +} + +NsmErrorStatus_e CAmControlSender::hookSystemLifecycleRequest(const uint32_t Request, const uint32_t RequestId) +{ + assert(mController); + return (mController->hookSystemLifecycleRequest(Request,RequestId)); +} + +/**for testing only contructor - do not use ! + * + */ +CAmControlSender::CAmControlSender() : + receiverCallbackT(this, &CAmControlSender::receiverCallback),// + checkerCallbackT(this, &CAmControlSender::checkerCallback),// + dispatcherCallbackT(this, &CAmControlSender::dispatcherCallback), // + mPipe(), // + mlibHandle(NULL), // + mController(NULL), // + mSignal(0) +{ + logInfo("CAmControlSender was loaded in test mode!"); +} + +bool CAmControlSender::dispatcherCallback(const sh_pollHandle_t handle, void* userData) +{ + (void)handle; + (void)userData; + setControllerRundown(mSignal); + return (false); +} + } diff --git a/AudioManagerDaemon/src/CAmDatabaseHandler.cpp b/AudioManagerDaemon/src/CAmDatabaseHandler.cpp index 2e2fa7e..4e9e51e 100644 --- a/AudioManagerDaemon/src/CAmDatabaseHandler.cpp +++ b/AudioManagerDaemon/src/CAmDatabaseHandler.cpp @@ -427,6 +427,9 @@ am_Error_e CAmDatabaseHandler::enterSinkDB(const am_Sink_s & sinkData, am_sinkID if (!this->sqQuery(command)) return (E_DATABASE_ERROR); command = "CREATE TABLE SinkSoundProperty" + i2s(sinkID) + std::string("(soundPropertyType INTEGER, value INTEGER)"); + if (!this->sqQuery(command)) + return (E_DATABASE_ERROR); + command = "CREATE TABLE SinkNotificationConfiguration" + i2s(sinkID) + std::string("(notificationType INTEGER, notificationStatus INTEGER, notificationParameter INTEGER)"); if (!this->sqQuery(command)) return (E_DATABASE_ERROR); @@ -463,6 +466,24 @@ am_Error_e CAmDatabaseHandler::enterSinkDB(const am_Sink_s & sinkData, am_sinkID MY_SQLITE_RESET(query) } + //Fill NotificationConfigurations + command = "INSERT INTO SinkNotificationConfiguration" + i2s(sinkID) + std::string("(notificationType,notificationStatus,notificationParameter) VALUES (?,?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator NotificationConfigurationIterator(sinkData.listNotificationConfigurations.begin()); + for (; NotificationConfigurationIterator < sinkData.listNotificationConfigurations.end(); ++NotificationConfigurationIterator) + { + MY_SQLITE_BIND_INT(query, 1, NotificationConfigurationIterator->notificationType) + MY_SQLITE_BIND_INT(query, 2, NotificationConfigurationIterator->notificationStatus) + MY_SQLITE_BIND_INT(query, 3, NotificationConfigurationIterator->notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::enterSinkDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + if (sinkData.visible == true) { command = "CREATE TABLE SinkMainSoundProperty" + i2s(sinkID) + std::string("(soundPropertyType INTEGER, value INTEGER)"); @@ -486,6 +507,29 @@ am_Error_e CAmDatabaseHandler::enterSinkDB(const am_Sink_s & sinkData, am_sinkID MY_SQLITE_RESET(query) } MY_SQLITE_FINALIZE(query) + + //now we got MainNotificationConfigurations as well + command = "CREATE TABLE SinkMainNotificationConfiguration" + i2s(sinkID) + std::string("(notificationType INTEGER, notificationStatus INTEGER, notificationParameter INTEGER)"); + if (!this->sqQuery(command)) + return (E_DATABASE_ERROR); + + command = "INSERT INTO SinkMainNotificationConfiguration" + i2s(sinkID) + std::string("(notificationType,notificationStatus,notificationParameter) VALUES (?,?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator mainNotificationConfigurationIterator(sinkData.listMainNotificationConfigurations.begin()); + for (; mainNotificationConfigurationIterator < sinkData.listMainNotificationConfigurations.end(); ++mainNotificationConfigurationIterator) + { + MY_SQLITE_BIND_INT(query, 1, mainNotificationConfigurationIterator->notificationType) + MY_SQLITE_BIND_INT(query, 2, mainNotificationConfigurationIterator->notificationStatus) + MY_SQLITE_BIND_INT(query, 3, mainNotificationConfigurationIterator->notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::enterSinkDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) } logInfo("DatabaseHandler::enterSinkDB entered new sink with name", sinkData.name, "domainID:", sinkData.domainID, "classID:", sinkData.sinkClassID, "volume:", sinkData.volume, "assigned ID:", sinkID); @@ -800,6 +844,9 @@ am_Error_e CAmDatabaseHandler::enterSourceDB(const am_Source_s & sourceData, am_ command = "CREATE TABLE SourceSoundProperty" + i2s(sourceID) + std::string("(soundPropertyType INTEGER, value INTEGER)"); if (!this->sqQuery(command)) return (E_DATABASE_ERROR); + command = "CREATE TABLE SourceNotificationConfiguration" + i2s(sourceID) + std::string("(notificationType INTEGER, notificationStatus INTEGER, notificationParameter INTEGER)"); + if (!this->sqQuery(command)) + return (E_DATABASE_ERROR); //fill ConnectionFormats command = "INSERT INTO SourceConnectionFormat" + i2s(sourceID) + std::string("(soundFormat) VALUES (?)"); @@ -835,7 +882,23 @@ am_Error_e CAmDatabaseHandler::enterSourceDB(const am_Source_s & sourceData, am_ MY_SQLITE_RESET(query) } - MY_SQLITE_FINALIZE(query) + //Fill NotificationConfigurations + command = "INSERT INTO SourceNotificationConfiguration" + i2s(sourceID) + std::string("(notificationType,notificationStatus,notificationParameter) VALUES (?,?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator NotificationConfigurationIterator(sourceData.listNotificationConfigurations.begin()); + for (; NotificationConfigurationIterator < sourceData.listNotificationConfigurations.end(); ++NotificationConfigurationIterator) + { + MY_SQLITE_BIND_INT(query, 1, NotificationConfigurationIterator->notificationType) + MY_SQLITE_BIND_INT(query, 2, NotificationConfigurationIterator->notificationStatus) + MY_SQLITE_BIND_INT(query, 3, NotificationConfigurationIterator->notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::enterSinkDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } if (sourceData.visible == true) { @@ -860,6 +923,29 @@ am_Error_e CAmDatabaseHandler::enterSourceDB(const am_Source_s & sourceData, am_ MY_SQLITE_RESET(query) } MY_SQLITE_FINALIZE(query) + + //now we got MainNotificationConfigurations as well + command = "CREATE TABLE SourceMainNotificationConfiguration" + i2s(sourceID) + std::string("(notificationType INTEGER, notificationStatus INTEGER, notificationParameter INTEGER)"); + if (!this->sqQuery(command)) + return (E_DATABASE_ERROR); + + command = "INSERT INTO SourceMainNotificationConfiguration" + i2s(sourceID) + std::string("(notificationType,notificationStatus,notificationParameter) VALUES (?,?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator mainNotificationConfigurationIterator(sourceData.listMainNotificationConfigurations.begin()); + for (; mainNotificationConfigurationIterator < sourceData.listMainNotificationConfigurations.end(); ++mainNotificationConfigurationIterator) + { + MY_SQLITE_BIND_INT(query, 1, mainNotificationConfigurationIterator->notificationType) + MY_SQLITE_BIND_INT(query, 2, mainNotificationConfigurationIterator->notificationStatus) + MY_SQLITE_BIND_INT(query, 3, mainNotificationConfigurationIterator->notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::enterSinkDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) } logInfo("DatabaseHandler::enterSourceDB entered new source with name", sourceData.name, "domainID:", sourceData.domainID, "classID:", sourceData.sourceClassID, "visible:", sourceData.visible, "assigned ID:", sourceID); @@ -1250,16 +1336,22 @@ am_Error_e CAmDatabaseHandler::removeSinkDB(const am_sinkID_t sinkID) std::string command1 = "DROP table SinkConnectionFormat" + i2s(sinkID); std::string command2 = "DROP table SinkSoundProperty" + i2s(sinkID); std::string command3 = "DROP table SinkMainSoundProperty" + i2s(sinkID); + std::string command4 = "DROP table SinkNotificationConfiguration" + i2s(sinkID); + std::string command5 = "DROP table SinkMainNotificationConfiguration" + i2s(sinkID); if (!sqQuery(command)) return (E_DATABASE_ERROR); if (!sqQuery(command1)) return (E_DATABASE_ERROR); if (!sqQuery(command2)) return (E_DATABASE_ERROR); + if (!sqQuery(command4)) + return (E_DATABASE_ERROR); if (visible) //only drop table if it ever existed { if (!sqQuery(command3)) return (E_DATABASE_ERROR); + if (!sqQuery(command5)) + return (E_DATABASE_ERROR); } logInfo("DatabaseHandler::removeSinkDB removed:", sinkID); @@ -2148,12 +2240,14 @@ am_Error_e CAmDatabaseHandler::getListConnections(std::vector & am_Error_e CAmDatabaseHandler::getListSinks(std::vector & listSinks) const { listSinks.clear(); - sqlite3_stmt* query = NULL, *qConnectionFormat = NULL, *qSoundProperty = NULL, *qMAinSoundProperty = NULL; + sqlite3_stmt* query = NULL, *qConnectionFormat = NULL, *qSoundProperty = NULL, *qNotificationConfiguration= NULL, *qMAinSoundProperty = NULL, *qMainNotificationConfiguration= NULL; int eCode = 0; am_Sink_s temp; am_ConnectionFormat_e tempConnectionFormat; am_SoundProperty_s tempSoundProperty; am_MainSoundProperty_s tempMainSoundProperty; + am_NotificationConfiguration_s tempNotificationConfiguration; + am_NotificationConfiguration_s tempMainNotificationConfiguration; std::string command = "SELECT name, domainID, sinkClassID, volume, visible, availability, availabilityReason, muteState, mainVolume, sinkID FROM " + std::string(SINK_TABLE) + " WHERE reserved=0"; MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) @@ -2193,6 +2287,19 @@ am_Error_e CAmDatabaseHandler::getListSinks(std::vector & listSinks) MY_SQLITE_FINALIZE(qSoundProperty) + //read out notifications + std::string commandNotificationConfiguration = "SELECT notificationType, notificationStatus, notificationParameter FROM SinkNotificationConfiguration" + i2s(temp.sinkID); + MY_SQLITE_PREPARE_V2(mpDatabase, commandNotificationConfiguration.c_str(), -1, &qNotificationConfiguration, NULL) + while ((eCode = sqlite3_step(qNotificationConfiguration)) == SQLITE_ROW) + { + tempNotificationConfiguration.notificationType = static_cast (sqlite3_column_int(qNotificationConfiguration, 0)); + tempNotificationConfiguration.notificationStatus = static_cast (sqlite3_column_int(qNotificationConfiguration, 1)); + tempNotificationConfiguration.notificationParameter = static_cast (sqlite3_column_int(qNotificationConfiguration, 2)); + temp.listNotificationConfigurations.push_back(tempNotificationConfiguration); + } + + MY_SQLITE_FINALIZE(qNotificationConfiguration) + //read out MainSoundProperties if sink is visible if(temp.visible) { @@ -2206,6 +2313,19 @@ am_Error_e CAmDatabaseHandler::getListSinks(std::vector & listSinks) } MY_SQLITE_FINALIZE(qMAinSoundProperty) + + //and mainNotificationConfigurations + std::string commandMainNotificationConfiguration = "SELECT notificationType, notificationStatus, notificationParameter FROM SinkMainNotificationConfiguration" + i2s(temp.sinkID); + MY_SQLITE_PREPARE_V2(mpDatabase, commandMainNotificationConfiguration.c_str(), -1, &qMainNotificationConfiguration, NULL) + while ((eCode = sqlite3_step(qMainNotificationConfiguration)) == SQLITE_ROW) + { + tempMainNotificationConfiguration.notificationType = static_cast (sqlite3_column_int(qMainNotificationConfiguration, 0)); + tempMainNotificationConfiguration.notificationStatus = static_cast (sqlite3_column_int(qMainNotificationConfiguration, 1)); + tempMainNotificationConfiguration.notificationParameter = static_cast (sqlite3_column_int(qMainNotificationConfiguration, 2)); + temp.listMainNotificationConfigurations.push_back(tempMainNotificationConfiguration); + } + + MY_SQLITE_FINALIZE(qMainNotificationConfiguration) } listSinks.push_back(temp); @@ -4254,6 +4374,543 @@ am_Error_e am::CAmDatabaseHandler::peekSourceClassID(const std::string & name, a return (returnVal); } + +am_Error_e CAmDatabaseHandler::changeSource(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector listSoundProperties, const std::vector listConnectionFormats, const std::vector listMainSoundProperties) +{ + assert(sourceID!=0); + + sqlite3_stmt* query = NULL; + int eCode = 0; + std::string command; + am_sourceClass_t sourceClassOut(sourceClassID); + std::vector listMainSoundPropertiesOut(listMainSoundProperties); + + if (!existSource(sourceID)) + { + return (E_NON_EXISTENT); + } + + //check if sinkClass needs to be changed + if (sourceID!=0) + { + command = "UPDATE"+ std::string(SINK_TABLE)+ " SET sourceClassID=? WHERE sourceID=" + i2s(sourceID); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + MY_SQLITE_BIND_INT(query, 1, sourceClassID) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_FINALIZE(query); + } + + else //we need to read out the active one + { + command = "SELECT sourceClassID FROM " + std::string(SINK_TABLE) + " WHERE reserved=0 and sourceID=" + i2s(sourceID); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + + while ((eCode = sqlite3_step(query)) == SQLITE_ROW) + { + sourceClassOut = sqlite3_column_int(query, 0); + } + MY_SQLITE_FINALIZE(query) + } + + //check if soundProperties need to be updated + if (!listSoundProperties.empty()) + { + //first we drop the table + command = "DELETE from SourceSoundProperty" + i2s(sourceID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + //then we'll have a new one + //Fill SinkSoundProperties + command = "INSERT INTO SourceSoundProperty" + i2s(sourceID) + std::string("(soundPropertyType,value) VALUES (?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator SoundPropertyIterator = listSoundProperties.begin(); + for (; SoundPropertyIterator < listSoundProperties.end(); ++SoundPropertyIterator) + { + MY_SQLITE_BIND_INT(query, 1, SoundPropertyIterator->type) + MY_SQLITE_BIND_INT(query, 2, SoundPropertyIterator->value) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + + //check if we have to update the list of connectionformats + if (!listConnectionFormats.empty()) + { + //first clear the table + command = "DELETE from SourceConnectionFormat" + i2s(sourceID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + //fill ConnectionFormats + command = "INSERT INTO SourceConnectionFormat" + i2s(sourceID) + std::string("(soundFormat) VALUES (?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator connectionFormatIterator = listConnectionFormats.begin(); + for (; connectionFormatIterator < listConnectionFormats.end(); ++connectionFormatIterator) + { + MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + + //then we need to check if we need to update the listMainSoundProperties + if (!listMainSoundProperties.empty() && sourceVisible(sourceID)) + { + command = "DELETE from SourceMainSoundProperty" + i2s(sourceID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + //Fill MainSinkSoundProperties + command = "INSERT INTO SourceMainSoundProperty" + i2s(sourceID) + std::string("(soundPropertyType,value) VALUES (?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator mainSoundPropertyIterator = listMainSoundProperties.begin(); + for (; mainSoundPropertyIterator < listMainSoundProperties.end(); ++mainSoundPropertyIterator) + { + MY_SQLITE_BIND_INT(query, 1, mainSoundPropertyIterator->type) + MY_SQLITE_BIND_INT(query, 2, mainSoundPropertyIterator->value) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + else //read out the properties + { + getListMainSourceSoundProperties(sourceID,listMainSoundPropertiesOut); + } + + logInfo("DatabaseHandler::changeSource changed changeSink of source:", sourceID); + + if (mpDatabaseObserver != NULL) + { + mpDatabaseObserver->sourceUpdated(sourceID,sourceClassOut,listMainSoundPropertiesOut,sourceVisible(sourceID)); + } + + return (E_OK); + +} + +am_Error_e CAmDatabaseHandler::changeSink(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector listSoundProperties, const std::vector listConnectionFormats, const std::vector listMainSoundProperties) +{ + assert(sinkID!=0); + + sqlite3_stmt* query = NULL; + int eCode = 0; + std::string command; + am_sinkClass_t sinkClassOut(sinkClassID); + std::vector listMainSoundPropertiesOut(listMainSoundProperties); + + if (!existSink(sinkID)) + { + return (E_NON_EXISTENT); + } + + //check if sinkClass needs to be changed + if (sinkClassID!=0) + { + command = "UPDATE"+ std::string(SINK_TABLE)+ " SET sinkClassID=? WHERE sinkID=" + i2s(sinkID); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + MY_SQLITE_BIND_INT(query, 1, sinkClassID) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_FINALIZE(query); + } + + else //we need to read out the active one + { + command = "SELECT sinkClassID FROM " + std::string(SINK_TABLE) + " WHERE reserved=0 and sinkID=" + i2s(sinkID); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + + while ((eCode = sqlite3_step(query)) == SQLITE_ROW) + { + sinkClassOut = sqlite3_column_int(query, 0); + } + MY_SQLITE_FINALIZE(query) + } + + //check if soundProperties need to be updated + if (!listSoundProperties.empty()) + { + //first we drop the table + command = "DELETE from SinkSoundProperty" + i2s(sinkID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + //then we'll have a new one + //Fill SinkSoundProperties + command = "INSERT INTO SinkSoundProperty" + i2s(sinkID) + std::string("(soundPropertyType,value) VALUES (?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator SoundPropertyIterator = listSoundProperties.begin(); + for (; SoundPropertyIterator < listSoundProperties.end(); ++SoundPropertyIterator) + { + MY_SQLITE_BIND_INT(query, 1, SoundPropertyIterator->type) + MY_SQLITE_BIND_INT(query, 2, SoundPropertyIterator->value) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + + //check if we have to update the list of connectionformats + if (!listConnectionFormats.empty()) + { + //first clear the table + command = "DELETE from SinkConnectionFormat" + i2s(sinkID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + //fill ConnectionFormats + command = "INSERT INTO SinkConnectionFormat" + i2s(sinkID) + std::string("(soundFormat) VALUES (?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator connectionFormatIterator = listConnectionFormats.begin(); + for (; connectionFormatIterator < listConnectionFormats.end(); ++connectionFormatIterator) + { + MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + + //then we need to check if we need to update the listMainSoundProperties + if (!listMainSoundProperties.empty() && sinkVisible(sinkID)) + { + command = "DELETE from SinkMainSoundProperty" + i2s(sinkID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + //Fill MainSinkSoundProperties + command = "INSERT INTO SinkMainSoundProperty" + i2s(sinkID) + std::string("(soundPropertyType,value) VALUES (?,?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator mainSoundPropertyIterator = listMainSoundProperties.begin(); + for (; mainSoundPropertyIterator < listMainSoundProperties.end(); ++mainSoundPropertyIterator) + { + MY_SQLITE_BIND_INT(query, 1, mainSoundPropertyIterator->type) + MY_SQLITE_BIND_INT(query, 2, mainSoundPropertyIterator->value) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeSink SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + else //read out the properties + { + getListMainSinkSoundProperties(sinkID,listMainSoundPropertiesOut); + } + + logInfo("DatabaseHandler::changeSink changed changeSink of sink:", sinkID); + + if (mpDatabaseObserver != NULL) + { + mpDatabaseObserver->sinkUpdated(sinkID,sinkClassOut,listMainSoundPropertiesOut,sinkVisible(sinkID)); + } + + return (E_OK); +} + +am_Error_e CAmDatabaseHandler::getListSinkMainNotificationConfigurations(const am_sinkID_t sinkID, std::vector& listMainNotificationConfigurations) +{ + assert(sinkID!=0); + if (!existSink(sinkID)) + return (E_DATABASE_ERROR); // todo: here we could change to non existen, but not shown in sequences + listMainNotificationConfigurations.clear(); + + sqlite3_stmt* query = NULL; + int eCode = 0; + am_NotificationConfiguration_s temp; + std::string command = "SELECT notificationType, notificationStatus, notificationParameter FROM SinkMainNotificationConfiguration" + i2s(sinkID); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + + while ((eCode = sqlite3_step(query)) == SQLITE_ROW) + { + temp.notificationType = static_cast(sqlite3_column_int(query, 0)); + temp.notificationStatus = static_cast(sqlite3_column_int(query, 1)); + temp.notificationParameter= static_cast(sqlite3_column_int(query, 2)); + listMainNotificationConfigurations.push_back(temp); + } + + if (eCode != SQLITE_DONE) + { + logError("DatabaseHandler::getListSinkMainNotificationConfigurations SQLITE error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + + MY_SQLITE_FINALIZE(query) + + return (E_OK); + +} + +am_Error_e CAmDatabaseHandler::getListSourceMainNotificationConfigurations(const am_sourceID_t sourceID, std::vector& listMainNotificationConfigurations) +{ + assert(sourceID!=0); + if (!existSource(sourceID)) + return (E_DATABASE_ERROR); // todo: here we could change to non existen, but not shown in sequences + listMainNotificationConfigurations.clear(); + + sqlite3_stmt* query = NULL; + int eCode = 0; + am_NotificationConfiguration_s temp; + std::string command = "SELECT notificationType, notificationStatus, notificationParameter FROM SourceMainNotificationConfiguration" + i2s(sourceID); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + + while ((eCode = sqlite3_step(query)) == SQLITE_ROW) + { + temp.notificationType = static_cast(sqlite3_column_int(query, 0)); + temp.notificationStatus = static_cast(sqlite3_column_int(query, 1)); + temp.notificationParameter= static_cast(sqlite3_column_int(query, 2)); + listMainNotificationConfigurations.push_back(temp); + } + + if (eCode != SQLITE_DONE) + { + logError("DatabaseHandler::getListSourceMainNotificationConfigurations SQLITE error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + + MY_SQLITE_FINALIZE(query) + + return (E_OK); +} + +am_Error_e CAmDatabaseHandler::changeMainSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + assert(sinkID!=0); + + sqlite3_stmt* query = NULL; + int eCode = 0; + std::string command; + + if (!existSink(sinkID)) + { + return (E_NON_EXISTENT); + } + command = "UPDATE SinkMainNotificationConfiguration" + i2s(sinkID) + " SET notificationStatus=?, notificationParameter=? WHERE notificationType=" + i2s(mainNotificationConfiguration.notificationType); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + MY_SQLITE_BIND_INT(query, 1, mainNotificationConfiguration.notificationStatus) + MY_SQLITE_BIND_INT(query, 2, mainNotificationConfiguration.notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeMainSinkNotificationConfigurationDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_FINALIZE(query) + + logInfo("DatabaseHandler::changeMainSinkNotificationConfigurationDB changed MainNotificationConfiguration of source:", sinkID, "type:", mainNotificationConfiguration.notificationType, "to status=", mainNotificationConfiguration.notificationStatus, "and parameter=",mainNotificationConfiguration.notificationParameter); + + if (mpDatabaseObserver) + mpDatabaseObserver->sinkMainNotificationConfigurationChanged(sinkID, mainNotificationConfiguration); + return (E_OK); +} + +am_Error_e CAmDatabaseHandler::changeMainSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + assert(sourceID!=0); + + sqlite3_stmt* query = NULL; + int eCode = 0; + std::string command; + + if (!existSource(sourceID)) + { + return (E_NON_EXISTENT); + } + command = "UPDATE SourceMainNotificationConfiguration" + i2s(sourceID) + " SET notificationStatus=?, notificationParameter=? WHERE notificationType=" + i2s(mainNotificationConfiguration.notificationType); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + MY_SQLITE_BIND_INT(query, 1, mainNotificationConfiguration.notificationStatus) + MY_SQLITE_BIND_INT(query, 2, mainNotificationConfiguration.notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeMainSourceNotificationConfigurationDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_FINALIZE(query) + + logInfo("DatabaseHandler::changeMainSourceNotificationConfigurationDB changed MainNotificationConfiguration of source:", sourceID, "type:", mainNotificationConfiguration.notificationType, "to status=", mainNotificationConfiguration.notificationStatus, "and parameter=",mainNotificationConfiguration.notificationParameter); + + if (mpDatabaseObserver) + mpDatabaseObserver->sourceMainNotificationConfigurationChanged(sourceID, mainNotificationConfiguration); + return (E_OK); +} + +am_Error_e CAmDatabaseHandler::changeGatewayDB(const am_gatewayID_t gatewayID, const std::vector listSourceConnectionFormats, const std::vector listSinkConnectionFormats, const std::vector convertionMatrix) +{ + assert(gatewayID!=0); + + sqlite3_stmt* query = NULL; + int eCode = 0; + std::string command; + + if (!existGateway(gatewayID)) + { + return (E_NON_EXISTENT); + } + + if (!listSourceConnectionFormats.empty()) + { + //clear Database + command = "DELETE from GatewaySourceFormat" + i2s(gatewayID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + //fill ConnectionFormats + command = "INSERT INTO GatewaySourceFormat" + i2s(gatewayID) + std::string("(soundFormat) VALUES (?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator connectionFormatIterator = listSourceConnectionFormats.begin(); + for (; connectionFormatIterator < listSourceConnectionFormats.end(); ++connectionFormatIterator) + { + MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::enterGatewayDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + + if (!listSinkConnectionFormats.empty()) + { + //clear Database + command = "DELETE from GatewaySinkFormat" + i2s(gatewayID); + if (!sqQuery(command)) + return (E_DATABASE_ERROR); + + command = "INSERT INTO GatewaySinkFormat" + i2s(gatewayID) + std::string("(soundFormat) VALUES (?)"); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + std::vector::const_iterator connectionFormatIterator = listSinkConnectionFormats.begin(); + for (; connectionFormatIterator < listSinkConnectionFormats.end(); ++connectionFormatIterator) + { + MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::enterGatewayDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_RESET(query) + } + MY_SQLITE_FINALIZE(query) + } + + if (!convertionMatrix.empty()) + { + mListConnectionFormat.clear(); + mListConnectionFormat.insert(std::make_pair(gatewayID, convertionMatrix)); + } + + logInfo("DatabaseHandler::changeGatewayDB changed Gateway with ID", gatewayID); + + //todo: check if observer needs to be adopted. + return (E_OK); +} + +am_Error_e CAmDatabaseHandler::changeSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s notificationConfiguration) +{ + assert(sinkID!=0); + + sqlite3_stmt* query = NULL; + int eCode = 0; + std::string command; + + if (!existSink(sinkID)) + { + return (E_NON_EXISTENT); + } + command = "UPDATE SinkNotificationConfiguration" + i2s(sinkID) + " SET notificationStatus=?, notificationParameter=? WHERE notificationType=" + i2s(notificationConfiguration.notificationType); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + MY_SQLITE_BIND_INT(query, 1, notificationConfiguration.notificationStatus) + MY_SQLITE_BIND_INT(query, 2, notificationConfiguration.notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeMainSinkNotificationConfigurationDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_FINALIZE(query) + + logInfo("DatabaseHandler::changeMainSinkNotificationConfigurationDB changed MainNotificationConfiguration of source:", sinkID, "type:", notificationConfiguration.notificationType, "to status=", notificationConfiguration.notificationStatus, "and parameter=",notificationConfiguration.notificationParameter); + + //todo:: inform obsever here... + return (E_OK); +} + +am_Error_e CAmDatabaseHandler::changeSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s notificationConfiguration) +{ + assert(sourceID!=0); + + sqlite3_stmt* query = NULL; + int eCode = 0; + std::string command; + + if (!existSource(sourceID)) + { + return (E_NON_EXISTENT); + } + command = "UPDATE SourceNotificationConfiguration" + i2s(sourceID) + " SET notificationStatus=?, notificationParameter=? WHERE notificationType=" + i2s(notificationConfiguration.notificationType); + MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL) + MY_SQLITE_BIND_INT(query, 1, notificationConfiguration.notificationStatus) + MY_SQLITE_BIND_INT(query, 2, notificationConfiguration.notificationParameter) + if ((eCode = sqlite3_step(query)) != SQLITE_DONE) + { + logError("DatabaseHandler::changeMainSourceNotificationConfigurationDB SQLITE Step error code:", eCode); + MY_SQLITE_FINALIZE(query) + return (E_DATABASE_ERROR); + } + MY_SQLITE_FINALIZE(query) + + logInfo("DatabaseHandler::changeSourceNotificationConfigurationDB changed MainNotificationConfiguration of source:", sourceID, "type:", notificationConfiguration.notificationType, "to status=", notificationConfiguration.notificationStatus, "and parameter=",notificationConfiguration.notificationParameter); + + //todo:: implement observer function + return (E_OK); +} + void CAmDatabaseHandler::createTables() { for (uint16_t i = 0; i < sizeof(databaseTables) / sizeof(databaseTables[0]); i++) diff --git a/AudioManagerDaemon/src/CAmDatabaseObserver.cpp b/AudioManagerDaemon/src/CAmDatabaseObserver.cpp index 426f5d2..506ec01 100644 --- a/AudioManagerDaemon/src/CAmDatabaseObserver.cpp +++ b/AudioManagerDaemon/src/CAmDatabaseObserver.cpp @@ -202,4 +202,27 @@ void CAmDatabaseObserver::timingInformationChanged(const am_mainConnectionID_t m { mSerializer.asyncCall(mCommandSender, &CAmCommandSender::cbTimingInformationChanged, mainConnection, time); } + +void CAmDatabaseObserver::sinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector& listMainSoundProperties, const bool visible) +{ + if (visible) + mSerializer.asyncCall >(mCommandSender, &CAmCommandSender::cbSinkUpdated, sinkID, sinkClassID, listMainSoundProperties); +} + +void CAmDatabaseObserver::sourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector& listMainSoundProperties, const bool visible) +{ + if (visible) + mSerializer.asyncCall >(mCommandSender, &CAmCommandSender::cbSinkUpdated, sourceID, sourceClassID, listMainSoundProperties); +} + +void CAmDatabaseObserver::sinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + mSerializer.asyncCall (mCommandSender, &CAmCommandSender::cbSinkMainNotificationConfigurationChanged, sinkID, mainNotificationConfiguration); +} + +void CAmDatabaseObserver::sourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) +{ + mSerializer.asyncCall(mCommandSender, &CAmCommandSender::cbSourceMainNotificationConfigurationChanged, sourceID, mainNotificationConfiguration); +} + } diff --git a/AudioManagerDaemon/src/CAmDbusWrapper.cpp b/AudioManagerDaemon/src/CAmDbusWrapper.cpp index 23fc27e..89c6122 100644 --- a/AudioManagerDaemon/src/CAmDbusWrapper.cpp +++ b/AudioManagerDaemon/src/CAmDbusWrapper.cpp @@ -302,7 +302,6 @@ void CAmDbusWrapper::toogleWatchDelegate(DBusWatch *watch, void *userData) iterator = mMapHandleWatch.find(watch); if (iterator != mMapHandleWatch.end()) mpSocketHandler->updateEventFlags(iterator->second, event); - logInfo("DBusWrapper::toogleWatchDelegate watch was toggeled"); } dbus_bool_t CAmDbusWrapper::addTimeout(DBusTimeout *timeout, void* userData) @@ -337,7 +336,6 @@ dbus_bool_t CAmDbusWrapper::addTimeoutDelegate(DBusTimeout *timeout, void* userD //save timeout in Socket context userData = timeout; - logInfo("DBusWrapper::addTimeoutDelegate a timeout was added, timeout",localTimeout," handle ", *handle); return (true); } @@ -366,8 +364,7 @@ void CAmDbusWrapper::removeTimeoutDelegate(DBusTimeout *timeout, void* userData) } } delete handle; - logInfo("DBusWrapper::removeTimeoutDelegate a timeout was removed"); -} + } void CAmDbusWrapper::toggleTimeout(DBusTimeout *timeout, void* userData) { @@ -446,12 +443,10 @@ void CAmDbusWrapper::toggleTimeoutDelegate(DBusTimeout *timeout, void* userData) { mpSocketHandler->stopTimer(*handle); } - logInfo("DBusWrapper::toggleTimeoutDelegate was called"); } void CAmDbusWrapper::dbusTimerCallback(sh_timerHandle_t handle, void *userData) { - logInfo("DBusWrapper::dbusTimerCallback was called"); assert(userData!=NULL); if (dbus_timeout_get_enabled((DBusTimeout*) userData)) { diff --git a/AudioManagerDaemon/src/CAmNodeStateCommunicator.cpp b/AudioManagerDaemon/src/CAmNodeStateCommunicator.cpp new file mode 100644 index 0000000..ce6fd62 --- /dev/null +++ b/AudioManagerDaemon/src/CAmNodeStateCommunicator.cpp @@ -0,0 +1,763 @@ +/** + * Copyright (C) 2012, BMW AG + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Christian Linke, christian.linke@bmw.de BMW 2012 + * + * \file CAmNodeStateCommunicator.cpp + * For further information see http://www.genivi.org/. + * + */ + +#include "CAmNodeStateCommunicator.h" +#include +#include +#include +#include +#include "CAmControlSender.h" +#include "shared/CAmDbusWrapper.h" +#include "shared/CAmDltWrapper.h" +#include "config.h" + +namespace am +{ + +static DBusObjectPathVTable gObjectPathVTable; + +CAmNodeStateCommunicator::CAmNodeStateCommunicator(CAmDbusWrapper* iDbusWrapper) : + mpDbusWrapper(iDbusWrapper), // + mpControlSender(NULL), // + mpDBusConnection(NULL) +{ + assert(mpDbusWrapper); + logInfo("CAmNodeStateCommunicator::CAmNodeStateCommunicator started"); + + //save the DBusConnection + mpDbusWrapper->getDBusConnection(mpDBusConnection); + assert(mpDBusConnection!=NULL); + + //register the path and the callback for receiving messages + std::string path("LifeCycleConsumer"); + gObjectPathVTable.message_function=CAmNodeStateCommunicator::receiveCallback; + mpDbusWrapper->registerCallback(&gObjectPathVTable, path, this); + + //now we need to make sure we catch the signals from the NSM: + dbus_bus_add_match(mpDBusConnection, "type=\'signal\',path=\'/org/genivi/NodeStateManager\'", NULL); + if (!dbus_connection_add_filter(mpDBusConnection, CAmNodeStateCommunicator::signalCallback, this, NULL)) + { + logError("CAmNodeStateCommunicator::CAmNodeStateCommunicator not enought memory!"); + throw std::runtime_error("CAmNodeStateCommunicator::CAmNodeStateCommunicator not enought memory!"); + } + dbus_connection_flush(mpDBusConnection); +} + +CAmNodeStateCommunicator::~CAmNodeStateCommunicator() +{} + +/** retrieves the actual restartReason + * + * @param restartReason + * @return E_OK on success + */ +am_Error_e CAmNodeStateCommunicator::nsmGetRestartReasonProperty(NsmRestartReason_e& restartReason) +{ + int32_t answer(0); + am_Error_e error=readIntegerProperty("RestartReason",answer); + restartReason=static_cast(answer); + return(error); +} + +/** retrieves the actual shutdownreason + * + * @param ShutdownReason + * @return E_OK on success + */ +am_Error_e CAmNodeStateCommunicator::nsmGetShutdownReasonProperty(NsmShutdownReason_e& ShutdownReason) +{ + int32_t answer(0); + am_Error_e error=readIntegerProperty("ShutdownReason",answer); + ShutdownReason=static_cast(answer); + return(error); +} + +/** retrieves the actual runnuing reason + * + * @param nsmRunningReason + * @return E_OK on success + */ +am_Error_e CAmNodeStateCommunicator::nsmGetRunningReasonProperty(NsmRunningReason_e& nsmRunningReason) +{ + int32_t answer(0); + am_Error_e error=readIntegerProperty("WakeUpReason",answer); + nsmRunningReason=static_cast(answer); + return(error); +} + +/** gets the node state + * + * @param nsmNodeState + * @return NsmErrorStatus_Ok on success + */ +NsmErrorStatus_e CAmNodeStateCommunicator::nsmGetNodeState(NsmNodeState_e& nsmNodeState) +{ + DBusError error; + dbus_error_init(&error); + + uint32_t nodeStateID; + uint32_t returnedError; + + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetNodeState"); + + if (!message) + { + logError("CAmNodeStateCommunicator::nsmGetNodeState dbus error:", error.message); + return (NsmErrorStatus_Dbus); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + if (!reply) + { + logError("CAmNodeStateCommunicator::nsmGetNodeState failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + + if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &nodeStateID, DBUS_TYPE_INT32, &returnedError, DBUS_TYPE_INVALID)) + return (NsmErrorStatus_Dbus); + + dbus_message_unref(reply); + + nsmNodeState=static_cast(nodeStateID); + return (static_cast(returnedError)); +} + +/** gets the session state for a session and seatID + * + * @param sessionName the name of the session + * @param seatID the seatID + * @param sessionState + * @return NsmErrorStatus_Ok on success + */ +NsmErrorStatus_e CAmNodeStateCommunicator::nsmGetSessionState(const std::string& sessionName, const NsmSeat_e& seatID, NsmSessionState_e& sessionState) +{ + DBusError error; + dbus_error_init(&error); + DBusMessageIter iter; + + uint32_t returnedError; + int32_t BsessionState(0); + + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetSessionState"); + + if (!message) + { + logError("CAmNodeStateCommunicator::nsmGetSessionState dbus error:", error.message); + return (NsmErrorStatus_Dbus); + } + + dbus_message_iter_init_append(message, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &sessionName)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &seatID)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + if (!reply) + { + logError("CAmNodeStateCommunicator::nsmGetSessionState failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + + if(!dbus_message_get_args(reply, &error, + DBUS_TYPE_INT32, &BsessionState, + DBUS_TYPE_INT32, &returnedError,DBUS_TYPE_INVALID)) + return (NsmErrorStatus_Dbus); + + dbus_message_unref(reply); + + sessionState=static_cast(BsessionState); + return (static_cast(returnedError)); +} + +/** gets the application mode + * + * @param applicationMode + * @return NsmErrorStatus_Ok on success + */ +NsmErrorStatus_e CAmNodeStateCommunicator::nsmGetApplicationMode(NsmApplicationMode_e& applicationMode) +{ + DBusError error; + dbus_error_init(&error); + + uint32_t BapplicationMode(0),returnedError(0); + + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetApplicationMode"); + + if (!message) + { + logError("CAmNodeStateCommunicator::nsmGetApplicationMode dbus error:", error.message); + return (NsmErrorStatus_Dbus); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + if (!reply) + { + logError("CAmNodeStateCommunicator::nsmGetApplicationMode failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + + if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &BapplicationMode, DBUS_TYPE_INT32, &returnedError, DBUS_TYPE_INVALID)) + return (NsmErrorStatus_Dbus); + + dbus_message_unref(reply); + + applicationMode=static_cast(BapplicationMode); + return (static_cast(returnedError)); +} + +/** this function registers the AudioManager as shutdown client at the NSM + * for more information check the Nodestatemanager + * @param shutdownMode the shutdownmode you wish to set + * @param timeoutMs the timeout you need to have + * @return NsmErrorStatus_Ok on success + */ +NsmErrorStatus_e CAmNodeStateCommunicator::nsmRegisterShutdownClient(const uint32_t shutdownMode, const uint32_t timeoutMs) +{ + DBusError error; + DBusMessageIter iter; + dbus_error_init(&error); + int16_t returnError(0); + std::string path = std::string(DBUS_SERVICE_OBJECT_PATH) + "/LifeCycleConsumer"; + const char* charPath = path.c_str(); + const char* service =DBUS_SERVICE_PREFIX; + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "RegisterShutdownClient"); + + if (!message) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient dbus error:", error.message); + return (NsmErrorStatus_Dbus); + } + dbus_message_iter_init_append(message, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &service)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &charPath)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &shutdownMode)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &timeoutMs)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + dbus_message_unref(message); + + if (!reply) + { + logError( "CAmRoutingDbusSend::send failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + + if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &returnError,DBUS_TYPE_INVALID)) + { + logError( "CAmRoutingDbusSend::send failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + dbus_message_unref(reply); + + return (static_cast(returnError)); + +} + +/** this function unregisters the AudioManager as shutdown client at the NSM + * + * @param shutdownMode + * @return NsmErrorStatus_Ok on success + */ +NsmErrorStatus_e CAmNodeStateCommunicator::nsmUnRegisterShutdownClient(const uint32_t shutdownMode) +{ + DBusError error; + DBusMessageIter iter; + dbus_error_init(&error); + int16_t returnError(0); + std::string path = std::string(DBUS_SERVICE_OBJECT_PATH) + "/LifeCycleConsumer"; + const char* charPath = path.c_str(); + const char* service =DBUS_SERVICE_PREFIX; + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "UnRegisterShutdownClient"); + + if (!message) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient dbus error:", error.message); + return (NsmErrorStatus_Dbus); + } + dbus_message_iter_init_append(message, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &service)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &charPath)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &shutdownMode)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient no more memory"); + return (NsmErrorStatus_Dbus); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + dbus_message_unref(message); + + if (!reply) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + + if(!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &returnError, DBUS_TYPE_INVALID)) + { + logError( "CAmNodeStateCommunicator::nsmRegisterShutdownClient failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + dbus_message_unref(reply); + + return (static_cast(returnError)); +} + +/** returns the interface version + * + * @param version + * @return E_OK on success + */ +am_Error_e CAmNodeStateCommunicator::nsmGetInterfaceVersion(uint32_t& version) +{ + DBusError error; + dbus_error_init(&error); + + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "GetInterfaceVersion"); + + if (!message) + { + logError("CAmNodeStateCommunicator::nsmGetInterfaceVersion dbus error:", error.message); + return (E_UNKNOWN); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + + dbus_message_unref(message); + + if (!reply) + { + logError("CAmNodeStateCommunicator::nsmGetInterfaceVersion failed, dbus error", error.message); + return (E_UNKNOWN); + } + + if(!dbus_message_get_args(reply, &error, DBUS_TYPE_UINT32, &version, DBUS_TYPE_INVALID)) + { + logError("CAmNodeStateCommunicator::nsmGetInterfaceVersion failed, dbus error", error.message); + return (E_UNKNOWN); + } + + dbus_message_unref(reply); + + return (E_OK); +} + +/** sends out the Lifecycle request complete message + * + * @param RequestId + * @param status + * @return NsmErrorStatus_Ok on success + */ +NsmErrorStatus_e CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete(const uint32_t RequestId, const NsmErrorStatus_e status) +{ + DBusError error; + DBusMessageIter iter; + dbus_error_init(&error); + int16_t returnError(0); + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, NSM_INTERFACE, "LifecycleRequestComplete"); + + if (!message) + { + logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete dbus error:", error.message); + return (NsmErrorStatus_Dbus); + } + dbus_message_iter_init_append(message, &iter); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &RequestId)) + { + logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete no more memory"); + return (NsmErrorStatus_Dbus); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32,&status)) + { + logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete no more memory"); + return (NsmErrorStatus_Dbus); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + dbus_message_unref(message); + + if (!reply) + { + logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + + if(!dbus_message_get_args(reply, &error,DBUS_TYPE_INT32, &returnError, DBUS_TYPE_INVALID)) + { + logError( "CAmNodeStateCommunicator::nsmSendLifecycleRequestComplete failed, dbus error", error.message); + return (NsmErrorStatus_Dbus); + } + dbus_message_unref(reply); + + return (static_cast(returnError)); +} + +void CAmNodeStateCommunicator::registerControlSender(CAmControlSender* iControlSender) +{ + assert(iControlSender); + mpControlSender=iControlSender; +} + +DBusHandlerResult CAmNodeStateCommunicator::receiveCallback(DBusConnection* conn, DBusMessage* msg, void* user_data) +{ + CAmNodeStateCommunicator* instance = static_cast(user_data); + assert(instance); + return (instance->receiveCallbackDelegate(conn,msg)); +} + +DBusHandlerResult CAmNodeStateCommunicator::receiveCallbackDelegate(DBusConnection* conn, DBusMessage* msg) +{ + if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) + { + sendIntrospection(conn, msg); + return (DBUS_HANDLER_RESULT_HANDLED); + } + else + { + DBusMessage * returnMessage; + dbus_uint16_t Request(0),RequestId(0); + //no introspection - ok. So we are only interested in out LifecycleRequest message... + std::string method(dbus_message_get_member(msg)); + if (method=="LifecycleRequest") + { + DBusMessageIter iter,replyIter; + if (!dbus_message_iter_init(msg, &iter)) + { + logError("CAmNodeStateCommunicator::receiveCallbackDelegate DBus Message has no arguments!"); + returnMessage = dbus_message_new_error(msg,DBUS_ERROR_INVALID_ARGS, "DBUS Message has no arguments!"); + sendMessage(returnMessage,msg); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_UINT32) + { + logError("CAmNodeStateCommunicator::receiveCallbackDelegate DBus Message has invalid arguments!"); + returnMessage = dbus_message_new_error(msg,DBUS_ERROR_INVALID_ARGS,"DBus argument is no uint16_t!"); + sendMessage(returnMessage,msg); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + dbus_message_iter_get_basic(&iter, &Request); + dbus_message_iter_next(&iter); + + if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_UINT32) + { + logError("CAmNodeStateCommunicator::receiveCallbackDelegate DBus Message has invalid arguments!"); + returnMessage = dbus_message_new_error(msg,DBUS_ERROR_INVALID_ARGS,"DBus argument is no uint16_t!"); + sendMessage(returnMessage,msg); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + dbus_message_iter_get_basic(&iter, &RequestId); + + assert(mpControlSender); + NsmErrorStatus_e returnError = mpControlSender->hookSystemLifecycleRequest(static_cast(Request),static_cast(RequestId)); + + returnMessage = dbus_message_new_method_return(msg); + + if (returnMessage == NULL) + { + logError("CAmNodeStateCommunicator::receiveCallbackDelegate Cannot allocate DBus message!"); + returnMessage = dbus_message_new_error(msg,DBUS_ERROR_NO_MEMORY,"Cannot create reply!"); + sendMessage(returnMessage,msg); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + dbus_message_iter_init_append(returnMessage, &replyIter); + + if (!dbus_message_iter_append_basic(&replyIter, DBUS_TYPE_INT32, &returnError)) + { + logError("CAmNodeStateCommunicator::receiveCallbackDelegate Cannot allocate DBus message!"); + returnMessage = dbus_message_new_error(msg,DBUS_ERROR_NO_MEMORY,"Cannot create reply!"); + } + sendMessage(returnMessage,msg); + return (DBUS_HANDLER_RESULT_HANDLED); + } + } + return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); +} + +void CAmNodeStateCommunicator::sendIntrospection(DBusConnection* conn, DBusMessage* msg) +{ + assert(conn != NULL); + assert(msg != NULL); + DBusMessage* reply; + DBusMessageIter args; + dbus_uint32_t serial = 0; + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + std::string fullpath(NSM_INTROSPECTION_FILE); + std::ifstream in(fullpath.c_str(), std::ifstream::in); + if (!in) + { + logError("IAmCommandReceiverShadow::sendIntrospection could not load xml file ",fullpath); + throw std::runtime_error("IAmCommandReceiverShadow::sendIntrospection Could not load introspecton XML"); + } + std::string introspect((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + const char* string = introspect.c_str(); + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string)) + { + logError( "CAmNodeStateCommunicator::sendIntrospection DBUS handler Out Of Memory!"); + } + + // send the reply && flush the connection + if (!dbus_connection_send(conn, reply, &serial)) + { + logError( "CAmNodeStateCommunicator::sendIntrospection DBUS handler Out Of Memory!"); + } + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); +} + +void CAmNodeStateCommunicator::sendMessage(DBusMessage* message, DBusMessage* origMessage) +{ + dbus_uint32_t serial = dbus_message_get_serial(origMessage); + + dbus_connection_send(mpDBusConnection, message, &serial); + dbus_connection_flush(mpDBusConnection); + dbus_message_unref(message); +} + +DBusHandlerResult CAmNodeStateCommunicator::signalCallback(DBusConnection* conn, DBusMessage* msg, void* user_data) +{ + (void) conn; + CAmNodeStateCommunicator* instance(static_cast(user_data)); + std::string interface = dbus_message_get_interface(msg); + std::string member = dbus_message_get_member(msg); + + if (interface=="org.genivi.NodeStateManager.Consumer") + { + if (member=="NodeState") + { + int32_t nodeState; + DBusMessageIter iter; + if (!dbus_message_iter_init(msg, &iter)) + { + logError("CAmNodeStateCommunicator::signalCallback NodeState DBus Message has no arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32) + { + logError("CAmNodeStateCommunicator::signalCallback NodeState DBus Message has invalid arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + dbus_message_iter_get_basic(&iter, &nodeState); + + logInfo("CAmNodeStateCommunicator::signalCallback got signal NodeState, with nodeState",nodeState); + + assert(instance->mpControlSender); + instance->mpControlSender->hookSystemNodeStateChanged(static_cast(nodeState)); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + else if (member=="NodeApplicationMode") + { + int32_t nodeApplicationMode; + DBusMessageIter iter; + if (!dbus_message_iter_init(msg, &iter)) + { + logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has no arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32) + { + logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + dbus_message_iter_get_basic(&iter, &nodeApplicationMode); + + logInfo("CAmNodeStateCommunicator::signalCallback got signal nodeApplicationMode, with applicationMode",nodeApplicationMode); + + assert(instance->mpControlSender); + instance->mpControlSender->hookSystemNodeApplicationModeChanged(static_cast(nodeApplicationMode)); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + else if (member=="SessionStateChanged") + { + std::string sessionName; + NsmSeat_e seatID; + NsmSessionState_e sessionState; + DBusMessageIter iter; + if (!dbus_message_iter_init(msg, &iter)) + { + logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has no arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_STRING) + { + logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + char * sessionNameChar; + dbus_message_iter_get_basic(&iter, &sessionNameChar); + sessionName=std::string(sessionNameChar); + dbus_message_iter_next(&iter); + + if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32) + { + logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + dbus_message_iter_get_basic(&iter, &seatID); + dbus_message_iter_next(&iter); + + if (dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32) + { + logError("CAmNodeStateCommunicator::signalCallback nodeApplicationMode DBus Message has invalid arguments!"); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + dbus_message_iter_get_basic(&iter, &sessionState); + + + logInfo("CAmNodeStateCommunicator::signalCallback got signal sessionStateChanged, with session",sessionName,"seatID=",seatID,"sessionState",sessionState); + + assert(instance->mpControlSender); + instance->mpControlSender->hookSystemSessionStateChanged(sessionName,seatID,sessionState); + return (DBUS_HANDLER_RESULT_HANDLED); + } + + else + { + return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + } + } + else + { + return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + } + printf("asdasdas\n"); + return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); +} + +am_Error_e CAmNodeStateCommunicator::readIntegerProperty(const std::string property, int32_t& value) +{ + DBusError error; + dbus_error_init(&error); + DBusMessageIter iter,iterVariant; + + DBusMessage * message = dbus_message_new_method_call(NSM_BUS_INTERFACE, NSM_PATH, "org.freedesktop.DBus.Properties", "Get"); + + if (!message) + { + logError("CAmNodeStateCommunicator::readIntegerProperty dbus error:", error.message); + return (E_UNKNOWN); + } + + + dbus_message_iter_init_append(message, &iter); + const char *interface=std::string(NSM_INTERFACE).c_str(); + const char *propertyChar=property.c_str(); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface)) + { + logError("CAmNodeStateCommunicator::readIntegerProperty append error"); + return (E_UNKNOWN); + } + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &propertyChar)) + { + logError("CAmNodeStateCommunicator::readIntegerProperty append error"); + return (E_UNKNOWN); + } + + DBusMessage* reply(dbus_connection_send_with_reply_and_block(mpDBusConnection, message, -1, &error)); + if (!reply) + { + logError("CAmNodeStateCommunicator::readIntegerProperty failed, dbus error", error.message); + return (E_UNKNOWN); + } + + dbus_message_iter_init(reply,&iterVariant); + if (dbus_message_iter_get_arg_type (&iterVariant)!= DBUS_TYPE_VARIANT) + { + logError("CAmNodeStateCommunicator::readIntegerProperty failed, dbus return type wrong"); + return (E_UNKNOWN); + } + DBusMessageIter subiter; + dbus_message_iter_recurse (&iterVariant, &subiter); + if (dbus_message_iter_get_arg_type (&subiter)!= DBUS_TYPE_INT32) + { + logError("CAmNodeStateCommunicator::readIntegerProperty failed, dbus return type wrong"); + return (E_UNKNOWN); + } + + dbus_message_iter_get_basic(&subiter,&value); + dbus_message_unref(reply); + + return (E_OK); +} + +} /* namespace am */ diff --git a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp index f0821a9..f1f0e09 100644 --- a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp +++ b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp @@ -41,7 +41,9 @@ CAmRoutingReceiver::CAmRoutingReceiver(CAmDatabaseHandler *iDatabaseHandler, CAm mListRundownHandles(), // handleCount(0), // mWaitStartup(false), // - mWaitRundown(false) + mWaitRundown(false), // + mLastStartupError(E_OK), // + mLastRundownError(E_OK) // { assert(mpDatabaseHandler!=NULL); assert(mpRoutingSender!=NULL); @@ -59,7 +61,9 @@ CAmRoutingReceiver::CAmRoutingReceiver(CAmDatabaseHandler *iDatabaseHandler, CAm mListRundownHandles(), // handleCount(0), // mWaitStartup(false), // - mWaitRundown(false) + mWaitRundown(false), + mLastStartupError(E_OK), // + mLastRundownError(E_OK) // { assert(mpDatabaseHandler!=NULL); assert(mpRoutingSender!=NULL); @@ -345,18 +349,22 @@ void CAmRoutingReceiver::getInterfaceVersion(std::string & version) const version = RoutingReceiveVersion; } -void CAmRoutingReceiver::confirmRoutingReady(const uint16_t handle) +void CAmRoutingReceiver::confirmRoutingReady(const uint16_t handle, const am_Error_e error) { + if (error!=E_OK) + mLastStartupError=error; mListStartupHandles.erase(std::remove(mListStartupHandles.begin(), mListStartupHandles.end(), handle), mListStartupHandles.end()); if (mWaitStartup && mListStartupHandles.empty()) - mpControlSender->confirmRoutingReady(); + mpControlSender->confirmRoutingReady(mLastStartupError); } -void CAmRoutingReceiver::confirmRoutingRundown(const uint16_t handle) +void CAmRoutingReceiver::confirmRoutingRundown(const uint16_t handle, const am_Error_e error) { + if (error!=E_OK) + mLastRundownError=error; mListRundownHandles.erase(std::remove(mListRundownHandles.begin(), mListRundownHandles.end(), handle), mListRundownHandles.end()); if (mWaitRundown && mListRundownHandles.empty()) - mpControlSender->confirmRoutingRundown(); + mpControlSender->confirmRoutingRundown(mLastRundownError); } uint16_t am::CAmRoutingReceiver::getStartupHandle() @@ -376,11 +384,88 @@ uint16_t am::CAmRoutingReceiver::getRundownHandle() void am::CAmRoutingReceiver::waitOnStartup(bool startup) { mWaitStartup = startup; + mLastStartupError=E_OK; +} + +am_Error_e CAmRoutingReceiver::updateGateway(const am_gatewayID_t gatewayID, std::vector listSourceFormats, const std::vector listSinkFormats, std::vector convertionMatrix) +{ + return (mpControlSender->hookSystemUpdateGateway(gatewayID,listSourceFormats,listSinkFormats,convertionMatrix)); +} + +am_Error_e CAmRoutingReceiver::updateSink(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector listSoundProperties, const std::vector listConnectionFormats, std::vector listMainSoundProperties) +{ + return (mpControlSender->hookSystemUpdateSink(sinkID,sinkClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties)); +} + +am_Error_e CAmRoutingReceiver::updateSource(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, std::vector listSoundProperties, std::vector listConnectionFormats, const std::vector listMainSoundProperties) +{ + return (mpControlSender->hookSystemUpdateSource(sourceID,sourceClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties)); +} + +void CAmRoutingReceiver::ackSetVolumes(const am_Handle_s handle, const std::vector listvolumes, const am_Error_e error) +{ + CAmRoutingSender::am_handleData_c handleData = mpRoutingSender->returnHandleData(handle); + if (error == E_OK && handleData.volumeID.sink != 0) + { + std::vector::const_iterator iterator (listvolumes.begin()); + + for (;iterator!=listvolumes.end();++iterator) + { + if (iterator->volumeType==VT_SINK) + { + mpDatabaseHandler->changeSinkVolume(iterator->volumeID.sink,iterator->volume); + } + else if (iterator->volumeType==VT_SOURCE) + { + mpDatabaseHandler->changeSourceVolume(iterator->volumeID.source,iterator->volume); + } + } + + } + mpRoutingSender->removeHandle(handle); + mpControlSender->cbAckSetVolume(handle,listvolumes,error); +} + +void CAmRoutingReceiver::ackSinkNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) +{ + CAmRoutingSender::am_handleData_c handleData = mpRoutingSender->returnHandleData(handle); + if (error == E_OK && handleData.sinkID != 0) + { + mpDatabaseHandler->changeSinkNotificationConfigurationDB(handleData.sinkID,*handleData.notificationConfiguration); + delete handleData.notificationConfiguration; + } + mpRoutingSender->removeHandle(handle); + mpControlSender->cbAckSetSinkNotificationConfiguration(handle,error); +} + +void CAmRoutingReceiver::ackSourceNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) +{ + CAmRoutingSender::am_handleData_c handleData = mpRoutingSender->returnHandleData(handle); + if (error == E_OK && handleData.sourceID != 0) + { + mpDatabaseHandler->changeSourceNotificationConfigurationDB(handleData.sourceID,*handleData.notificationConfiguration); + delete handleData.notificationConfiguration; + } + mpRoutingSender->removeHandle(handle); + mpControlSender->cbAckSetSourceNotificationConfiguration(handle,error); +} + +void CAmRoutingReceiver::hookSinkNotificationDataChange(const am_sinkID_t sinkID, const am_NotificationPayload_s payload) +{ + logInfo("CAmRoutingReceiver::hookSinkNotificationDataChange received, sinkID=",sinkID,"notificationType=",payload.notificationType,"notificationValue=",payload.notificationValue); + mpControlSender->hookSinkNotificationDataChanged(sinkID,payload); +} + +void CAmRoutingReceiver::hookSourceNotificationDataChange(const am_sourceID_t sourceID, const am_NotificationPayload_s payload) +{ + logInfo("CAmRoutingReceiver::hookSourceNotificationDataChange received, sinkID=",sourceID,"notificationType=",payload.notificationType,"notificationValue=",payload.notificationValue); + mpControlSender->hookSourceNotificationDataChanged(sourceID,payload); } void am::CAmRoutingReceiver::waitOnRundown(bool rundown) { mWaitRundown = rundown; + mLastRundownError=E_OK; } am_Error_e CAmRoutingSender::removeConnectionLookup(const am_connectionID_t connectionID) diff --git a/AudioManagerDaemon/src/CAmRoutingSender.cpp b/AudioManagerDaemon/src/CAmRoutingSender.cpp index f45f918..57892c7 100644 --- a/AudioManagerDaemon/src/CAmRoutingSender.cpp +++ b/AudioManagerDaemon/src/CAmRoutingSender.cpp @@ -596,6 +596,78 @@ void CAmRoutingSender::setRoutingRundown() } } +am_Error_e CAmRoutingSender::asyncSetVolumes(am_Handle_s& handle, const std::vector& listVolumes) +{ + am_handleData_c handleData; + IAmRoutingSend* pRoutingInterface(NULL); + if (listVolumes.empty()) + return (E_NOT_POSSIBLE); + + //we need an interface so lets get either the sink or source ID from the first entry in the listVolumes + if (listVolumes[0].volumeType==VT_SINK) + { + am_sinkID_t sinkID=listVolumes[0].volumeID.sink; + SinkInterfaceMap::iterator iter = mMapSinkInterface.begin(); + iter = mMapSinkInterface.find(sinkID); + if(iter!=mMapSinkInterface.end()) + pRoutingInterface=iter->second; + else + return(E_NON_EXISTENT); + } + + else if (listVolumes[0].volumeType==VT_SOURCE) + { + am_sourceID_t sourceID=listVolumes[0].volumeID.source; + SourceInterfaceMap::iterator iter = mMapSourceInterface.begin(); + iter = mMapSourceInterface.find(sourceID); + if (iter!=mMapSourceInterface.end()) + pRoutingInterface=iter->second; + else + return(E_NON_EXISTENT); + } + else + return (E_NON_EXISTENT); + + handleData.volumeID=listVolumes[0].volumeID; + handleData.listVolumes= new std::vector(listVolumes); + handle = createHandle(handleData, H_SETVOLUMES); + + mMapHandleInterface.insert(std::make_pair(+ handle.handle, pRoutingInterface)); + return (pRoutingInterface->asyncSetVolumes(handle, listVolumes)); +} + +am_Error_e CAmRoutingSender::asyncSetSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration) +{ + am_handleData_c handleData; + SinkInterfaceMap::iterator iter = mMapSinkInterface.begin(); + iter = mMapSinkInterface.find(sinkID); + if (iter != mMapSinkInterface.end()) + { + handleData.sinkID = sinkID; + handleData.notificationConfiguration = new am_NotificationConfiguration_s(notificationConfiguration); + handle = createHandle(handleData, H_SETSINKNOTIFICATION); + mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second)); + return (iter->second->asyncSetSinkNotificationConfiguration(handle, sinkID,notificationConfiguration)); + } + return (E_NON_EXISTENT); +} + +am_Error_e CAmRoutingSender::asyncSetSourceNotificationConfiguration(am_Handle_s& handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration) +{ + am_handleData_c handleData; + SourceInterfaceMap::iterator iter = mMapSourceInterface.begin(); + iter = mMapSourceInterface.find(sourceID); + if (iter != mMapSourceInterface.end()) + { + handleData.sourceID = sourceID; + handleData.notificationConfiguration = new am_NotificationConfiguration_s(notificationConfiguration); + handle = createHandle(handleData, H_SETSOURCENOTIFICATION); + mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second)); + return (iter->second->asyncSetSourceNotificationConfiguration(handle, sourceID,notificationConfiguration)); + } + return (E_NON_EXISTENT); +} + void CAmRoutingSender::unloadLibraries(void) { std::vector::iterator iterator = mListLibraryHandles.begin(); diff --git a/AudioManagerDaemon/src/CAmSocketHandler.cpp b/AudioManagerDaemon/src/CAmSocketHandler.cpp index f7c4ace..19d61c0 100644 --- a/AudioManagerDaemon/src/CAmSocketHandler.cpp +++ b/AudioManagerDaemon/src/CAmSocketHandler.cpp @@ -34,9 +34,9 @@ namespace am { -CAmSocketHandler* CAmSocketHandler::mInstance=NULL; - CAmSocketHandler::CAmSocketHandler() : + receiverCallbackT(this, &CAmSocketHandler::receiverCallback),// + checkerCallbackT(this, &CAmSocketHandler::checkerCallback),// mPipe(), mListPoll(), // mListTimer(), // @@ -44,12 +44,9 @@ CAmSocketHandler::CAmSocketHandler() : mLastInsertedHandle(0), // mLastInsertedPollHandle(0), // mRecreatePollfds(true), // - mStartTime(), // - receiverCallbackT(this, &CAmSocketHandler::receiverCallback),// - checkerCallbackT(this, &CAmSocketHandler::checkerCallback)// + mStartTime() // { gDispatchDone = 1; - mInstance=this; if (pipe(mPipe) == -1) { @@ -527,14 +524,6 @@ void CAmSocketHandler::exit_mainloop() write(mPipe[1], &p, sizeof(p)); } -void CAmSocketHandler::static_exit_mainloop() -{ - if (mInstance!=0) - { - mInstance->exit_mainloop(); - } -} - /** * is used to set the pointer for the ppoll command * @param buffertime diff --git a/AudioManagerDaemon/src/CAmTelnetMenuHelper.cpp b/AudioManagerDaemon/src/CAmTelnetMenuHelper.cpp index d820351..87f9659 100644 --- a/AudioManagerDaemon/src/CAmTelnetMenuHelper.cpp +++ b/AudioManagerDaemon/src/CAmTelnetMenuHelper.cpp @@ -1235,7 +1235,6 @@ void CAmTelnetMenuHelper::setSinkVolumeExec(std::queue& CmdQueue, i { am_volume_t volume = 0; am_sinkID_t sinkID = 0; - am_Handle_s handle; bool error = false; std::istringstream istream_sinkID(CmdQueue.front()); CmdQueue.pop(); diff --git a/AudioManagerDaemon/src/CAmWatchdog.cpp b/AudioManagerDaemon/src/CAmWatchdog.cpp index 15c7dcc..db34009 100755 --- a/AudioManagerDaemon/src/CAmWatchdog.cpp +++ b/AudioManagerDaemon/src/CAmWatchdog.cpp @@ -91,7 +91,6 @@ void CAmWatchdog::timerCallback(sh_timerHandle_t handle, void* userData) } mpCAmSocketHandler->restartTimer(handle); - logInfo("restarted watchdog "); } void CAmWatchdog::startWatchdog() diff --git a/AudioManagerDaemon/src/main.cpp b/AudioManagerDaemon/src/main.cpp index 6b84ba3..51003cf 100755 --- a/AudioManagerDaemon/src/main.cpp +++ b/AudioManagerDaemon/src/main.cpp @@ -57,6 +57,7 @@ #include "CAmControlReceiver.h" #include "CAmDatabaseObserver.h" #include "CAmWatchdog.h" +#include "CAmNodeStateCommunicator.h" #include "shared/CAmDltWrapper.h" #include "shared/CAmSocketHandler.h" @@ -265,15 +266,32 @@ static void signalHandler(int sig, siginfo_t *siginfo, void *context) (void) siginfo; (void) context; logInfo("signal handler was called, signal",sig); - //todo: maually fire the mainloop - CAmControlSender::CallsetControllerRundown(); - //deinit the DLT - CAmDltWrapper* inst(getWrapper()); - inst->deinit(); + switch (sig) + { + /*ctl +c lets call direct controllerRundown, because we might be blocked at the moment. + But there is the risk of interrupting something important */ + case SIGINT: + CAmControlSender::CallsetControllerRundown(sig); + break; - CAmSocketHandler::static_exit_mainloop(); + /* huch- we are getting killed. Better take the fast but risky way: */ + case SIGQUIT: + CAmControlSender::CallsetControllerRundown(sig); + break; + + /* more friendly here assuming systemd wants to stop us, so we can use the mainloop */ + case SIGTERM: + CAmControlSender::CallsetControllerRundownSafe(sig); + break; + /* looks friendly, too, so lets take the long run */ + case SIGHUP: + CAmControlSender::CallsetControllerRundownSafe(sig); + break; + default: + break; + } } void mainProgram() @@ -283,6 +301,7 @@ void mainProgram() #ifdef WITH_DBUS_WRAPPER CAmDbusWrapper iDBusWrapper(&iSocketHandler,dbusWrapperType); + CAmNodeStateCommunicator iNodeStateCommunicator(&iDBusWrapper); #endif /*WITH_DBUS_WRAPPER */ #ifdef WITH_SYSTEMD_WATCHDOG @@ -292,19 +311,21 @@ void mainProgram() CAmDatabaseHandler iDatabaseHandler(databasePath); CAmRoutingSender iRoutingSender(listRoutingPluginDirs); CAmCommandSender iCommandSender(listCommandPluginDirs); - CAmControlSender iControlSender(controllerPlugin); + CAmControlSender iControlSender(controllerPlugin,&iSocketHandler); CAmRouter iRouter(&iDatabaseHandler, &iControlSender); #ifdef WITH_DBUS_WRAPPER CAmCommandReceiver iCommandReceiver(&iDatabaseHandler, &iControlSender, &iSocketHandler, &iDBusWrapper); CAmRoutingReceiver iRoutingReceiver(&iDatabaseHandler, &iRoutingSender, &iControlSender, &iSocketHandler, &iDBusWrapper); - CAmControlReceiver iControlReceiver(&iDatabaseHandler, &iRoutingSender, &iCommandSender, &iSocketHandler, &iRouter); + CAmControlReceiver iControlReceiver(&iDatabaseHandler,&iRoutingSender,&iCommandSender,&iSocketHandler, &iRouter, &iNodeStateCommunicator); + iNodeStateCommunicator.registerControlSender(&iControlSender); #else /*WITH_DBUS_WRAPPER*/ CAmCommandReceiver iCommandReceiver(&iDatabaseHandler,&iControlSender,&iSocketHandler); CAmRoutingReceiver iRoutingReceiver(&iDatabaseHandler,&iRoutingSender,&iControlSender,&iSocketHandler); CAmControlReceiver iControlReceiver(&iDatabaseHandler,&iRoutingSender,&iCommandSender,&iSocketHandler, &iRouter); #endif /*WITH_DBUS_WRAPPER*/ + #ifdef WITH_TELNET CAmTelnetServer iTelnetServer(&iSocketHandler, &iCommandSender, &iCommandReceiver, &iRoutingSender, &iRoutingReceiver, &iControlSender, &iControlReceiver, &iDatabaseHandler, &iRouter, telnetport, maxConnections); CAmDatabaseObserver iObserver(&iCommandSender, &iRoutingSender, &iSocketHandler, &iTelnetServer); @@ -378,13 +399,18 @@ int main(int argc, char *argv[], char** envp) catch (std::exception& exc) { logError("The AudioManager ended by throwing the exception", exc.what()); - //todo: ergency exit here... call destructors etc... + std::cerr<<"The AudioManager ended by throwing an exception "<deinit(); + exit(0); } -- cgit v1.2.1