summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Linke <christian.linke@bmw.de>2015-11-04 13:55:55 +0000
committerChristian Linke <christian.linke@bmw.de>2015-11-04 13:55:55 +0000
commit28b3b278f06067ef7167cf0ffa56121ad9d3768a (patch)
treec515c71aaf7b21754d129ee7dc811bf37314f0c0
parent985bcfb9a3e83db5115d603925edccdf4dfba8c0 (diff)
downloadaudiomanager-28b3b278f06067ef7167cf0ffa56121ad9d3768a.tar.gz
* Bug fix 392. Some improvements regarding failed transactions in the router.
Signed-off-by: Christian Linke <christian.linke@bmw.de>
-rw-r--r--AudioManagerDaemon/include/CAmControlReceiver.h2
-rw-r--r--AudioManagerDaemon/include/CAmRoutingSender.h4
-rw-r--r--AudioManagerDaemon/src/CAmControlReceiver.cpp13
-rw-r--r--AudioManagerDaemon/src/CAmRoutingReceiver.cpp208
-rw-r--r--AudioManagerDaemon/src/CAmRoutingSender.cpp142
-rw-r--r--AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp68
-rw-r--r--AudioManagerDaemon/test/MockIAmRoutingSend.h3
-rw-r--r--include/IAmControl.h7
-rw-r--r--include/IAmRouting.h7
-rwxr-xr-xinclude/audiomanagertypes.h10
10 files changed, 376 insertions, 88 deletions
diff --git a/AudioManagerDaemon/include/CAmControlReceiver.h b/AudioManagerDaemon/include/CAmControlReceiver.h
index 88ba507..3f39189 100644
--- a/AudioManagerDaemon/include/CAmControlReceiver.h
+++ b/AudioManagerDaemon/include/CAmControlReceiver.h
@@ -42,7 +42,6 @@ class CAmNodeStateCommunicator;
class CAmControlReceiver: public IAmControlReceive
{
public:
- CAmControlReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmCommandSender *iCommandSender, CAmSocketHandler *iSocketHandler, CAmRouter* iRouter, CAmNodeStateCommunicator* iNodeStateCommunicator);
CAmControlReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmCommandSender *iCommandSender, CAmSocketHandler *iSocketHandler, CAmRouter* iRouter);
~CAmControlReceiver();
am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList);
@@ -141,6 +140,7 @@ public:
am_Error_e getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const;
am_Error_e getMainSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const;
am_Error_e getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e resyncConnectionState(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections);
private:
IAmDatabaseHandler* mDatabaseHandler; //!< pointer tto the databasehandler
diff --git a/AudioManagerDaemon/include/CAmRoutingSender.h b/AudioManagerDaemon/include/CAmRoutingSender.h
index 532809a..4a23428 100644
--- a/AudioManagerDaemon/include/CAmRoutingSender.h
+++ b/AudioManagerDaemon/include/CAmRoutingSender.h
@@ -77,6 +77,7 @@ public:
am_Error_e asyncSetVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes);
am_Error_e asyncSetSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration);
am_Error_e asyncSetSourceNotificationConfiguration(am_Handle_s& handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration);
+ am_Error_e resyncConnectionState(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections);
struct InterfaceNamePairs //!< is used to pair interfaces with busnames
{
@@ -109,7 +110,8 @@ public:
};
- am_handleData_c returnHandleData(const am_Handle_s handle) const; //!< returns the handle data associated with a handle
+ am_Error_e returnHandleData(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData) const; //!< returns the handle data associated with a handle
+ am_Error_e returnHandleDataAndRemove(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData); //!< returns the handle data associated with a handle and removes the handle
#ifdef UNIT_TEST //this is needed to test RoutingSender
friend class IAmRoutingBackdoor;
diff --git a/AudioManagerDaemon/src/CAmControlReceiver.cpp b/AudioManagerDaemon/src/CAmControlReceiver.cpp
index 198109d..c1c161e 100644
--- a/AudioManagerDaemon/src/CAmControlReceiver.cpp
+++ b/AudioManagerDaemon/src/CAmControlReceiver.cpp
@@ -71,7 +71,12 @@ am_Error_e CAmControlReceiver::connect(am_Handle_s & handle, am_connectionID_t &
tempConnection.delay=-1;
mDatabaseHandler->enterConnectionDB(tempConnection, connectionID);
- return (mRoutingSender->asyncConnect(handle, connectionID, sourceID, sinkID, format));
+ am_Error_e syncError(mRoutingSender->asyncConnect(handle, connectionID, sourceID, sinkID, format));
+ if (syncError)
+ {
+ mDatabaseHandler->removeConnection(connectionID);
+ }
+ return(syncError);
}
am_Error_e CAmControlReceiver::disconnect(am_Handle_s & handle, const am_connectionID_t connectionID)
@@ -591,5 +596,11 @@ am_Error_e CAmControlReceiver::getSourceSoundPropertyValue(const am_sourceID_t s
return (mDatabaseHandler->getSourceSoundPropertyValue(sourceID,propertyType,value));
}
+am_Error_e CAmControlReceiver::resyncConnectionState(const am_domainID_t domainID,std::vector<am_Connection_s>& listOfExistingConnections)
+{
+ logInfo("CAmControlReceiver::resyncConnectionState was called, domainID", domainID);
+ return (mRoutingSender->resyncConnectionState(domainID,listOfExistingConnections));
+}
+
}
diff --git a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp
index 4628136..1c20d5c 100644
--- a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp
+++ b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp
@@ -81,131 +81,193 @@ CAmRoutingReceiver::~CAmRoutingReceiver()
void CAmRoutingReceiver::ackConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
{
mpRoutingSender->removeHandle(handle);
- if (error == E_OK)
+ if (error == am_Error_e::E_OK)
{
mpDatabaseHandler->changeConnectionFinal(connectionID);
}
else
{
mpDatabaseHandler->removeConnection(connectionID);
+ mpRoutingSender->removeConnectionLookup(connectionID);
}
mpControlSender->cbAckConnect(handle, error);
}
void CAmRoutingReceiver::ackDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
{
+
+ //so we will remove the connection anyway no matter what is answered
mpRoutingSender->removeHandle(handle);
- if (error == E_OK)
- {
- mpDatabaseHandler->removeConnection(connectionID);
- if (mpRoutingSender->removeConnectionLookup(connectionID)!=E_OK)
- {
- logError("CAmRoutingReceiver::ackDisconnect could not remove connectionId from lookup");
- }
- }
+ mpDatabaseHandler->removeConnection(connectionID);
+ mpRoutingSender->removeConnectionLookup(connectionID);
mpControlSender->cbAckDisconnect(handle, error);
}
void CAmRoutingReceiver::ackSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
{
- CAmRoutingSender::am_handleData_c handleData = mpRoutingSender->returnHandleData(handle);
- if (error == E_OK && handleData.sinkID != 0)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
{
- //todo: check if volume in handleData is same than volume. React to it.
- mpDatabaseHandler->changeSinkVolume(handleData.sinkID, volume);
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error== am_Error_e::E_OK || am_Error_e::E_ABORTED)
+ {
+ mpDatabaseHandler->changeSinkVolume(handleData.sinkID, volume);
+ }
+
+ if(error == am_Error_e::E_OK || handleData.volume!=volume)
+ {
+ logError("ackSetSinkVolumeChange volumes do not match, requested volume",handleData.volume,"returned volume",volume);
}
- mpRoutingSender->removeHandle(handle);
mpControlSender->cbAckSetSinkVolumeChange(handle, volume, error);
}
void CAmRoutingReceiver::ackSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
{
- CAmRoutingSender::am_handleData_c handleData = mpRoutingSender->returnHandleData(handle);
- if (error == E_OK && handleData.sourceID != 0)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
{
- //todo: check if volume in handleData is same than volume. React to it.
- mpDatabaseHandler->changeSourceVolume(handleData.sourceID, volume);
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error== am_Error_e::E_OK || am_Error_e::E_ABORTED)
+ {
+ mpDatabaseHandler->changeSourceVolume(handleData.sourceID, volume);
+ }
+
+ if(error == E_OK || handleData.volume!=volume)
+ {
+ logError("ackSetSourceVolumeChange volumes do not match, requested volume",handleData.volume,"returned volume",volume);
}
- mpRoutingSender->removeHandle(handle);
mpControlSender->cbAckSetSourceVolumeChange(handle, volume, error);
}
void CAmRoutingReceiver::ackSetSourceState(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)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
{
- //todo: check if volume in handleData is same than volume. React to it.
- mpDatabaseHandler->changeSourceState(handleData.sourceID, handleData.sourceState);
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
}
- mpRoutingSender->removeHandle(handle);
+
+ //no error, so we can write the change into the database;
+ if (error == am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeSourceState(handleData.sourceID, handleData.sourceState);
+ }
+
mpControlSender->cbAckSetSourceState(handle, error);
}
void CAmRoutingReceiver::ackSetSinkSoundProperty(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)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error==am_Error_e::E_OK)
{
mpDatabaseHandler->changeSinkSoundPropertyDB(handleData.soundPropery, handleData.sinkID);
}
- mpRoutingSender->removeHandle(handle);
+
mpControlSender->cbAckSetSinkSoundProperty(handle, error);
}
void am::CAmRoutingReceiver::ackSetSinkSoundProperties(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)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error==am_Error_e::E_OK)
{
std::vector<am_SoundProperty_s>::const_iterator it = handleData.soundProperties->begin();
for (; it != handleData.soundProperties->end(); ++it)
{
mpDatabaseHandler->changeSinkSoundPropertyDB(*it, handleData.sinkID);
}
- delete handleData.soundProperties;
}
- mpRoutingSender->removeHandle(handle);
+
+ try
+ {
+ delete handleData.soundProperties;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSetSinkSoundProperties");
+ }
mpControlSender->cbAckSetSinkSoundProperties(handle, error);
}
void CAmRoutingReceiver::ackSetSourceSoundProperty(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)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
{
mpDatabaseHandler->changeSourceSoundPropertyDB(handleData.soundPropery, handleData.sourceID);
}
- mpRoutingSender->removeHandle(handle);
mpControlSender->cbAckSetSourceSoundProperty(handle, error);
}
void am::CAmRoutingReceiver::ackSetSourceSoundProperties(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)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
{
std::vector<am_SoundProperty_s>::const_iterator it = handleData.soundProperties->begin();
for (; it != handleData.soundProperties->end(); ++it)
{
mpDatabaseHandler->changeSourceSoundPropertyDB(*it, handleData.sourceID);
}
- delete handleData.soundProperties;
}
- mpRoutingSender->removeHandle(handle);
+
+ try
+ {
+ delete handleData.soundProperties;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSetSourceSoundProperties");
+ }
mpControlSender->cbAckSetSourceSoundProperties(handle, error);
}
void CAmRoutingReceiver::ackCrossFading(const am_Handle_s handle, const am_HotSink_e hotSink, const am_Error_e error)
{
- CAmRoutingSender::am_handleData_c handleData = mpRoutingSender->returnHandleData(handle);
- if (error == E_OK && handleData.crossfaderID != 0)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
{
- //todo: check if volume in handleData is same than volume. React to it.
mpDatabaseHandler->changeCrossFaderHotSink(handleData.crossfaderID, hotSink);
}
- mpRoutingSender->removeHandle(handle);
mpControlSender->cbAckCrossFade(handle, hotSink, error);
}
@@ -404,25 +466,50 @@ void am::CAmRoutingReceiver::waitOnStartup(bool startup)
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)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
{
mpDatabaseHandler->changeSinkNotificationConfigurationDB(handleData.sinkID,*handleData.notificationConfiguration);
- delete handleData.notificationConfiguration;
}
- mpRoutingSender->removeHandle(handle);
+
+ try
+ {
+ delete handleData.notificationConfiguration;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSinkNotificationConfiguration");
+ }
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)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
{
mpDatabaseHandler->changeSourceNotificationConfigurationDB(handleData.sourceID,*handleData.notificationConfiguration);
- delete handleData.notificationConfiguration;
}
- mpRoutingSender->removeHandle(handle);
+ try
+ {
+ delete handleData.notificationConfiguration;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSourceNotificationConfiguration");
+ }
mpControlSender->cbAckSetSourceNotificationConfiguration(handle,error);
}
@@ -448,8 +535,14 @@ am_Error_e CAmRoutingReceiver::updateSource(const am_sourceID_t sourceID, const
void CAmRoutingReceiver::ackSetVolumes(const am_Handle_s handle, const std::vector<am_Volumes_s>& listvolumes, const am_Error_e error)
{
- CAmRoutingSender::am_handleData_c handleData = mpRoutingSender->returnHandleData(handle);
- if (error == E_OK && handleData.volumeID.sink != 0)
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
{
std::vector<am_Volumes_s>::const_iterator iterator (listvolumes.begin());
@@ -466,7 +559,16 @@ void CAmRoutingReceiver::ackSetVolumes(const am_Handle_s handle, const std::vect
}
}
- mpRoutingSender->removeHandle(handle);
+
+ try
+ {
+ delete handleData.listVolumes;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSetVolumes");
+ }
+
mpControlSender->cbAckSetVolume(handle,listvolumes,error);
}
diff --git a/AudioManagerDaemon/src/CAmRoutingSender.cpp b/AudioManagerDaemon/src/CAmRoutingSender.cpp
index e419356..efd44e1 100644
--- a/AudioManagerDaemon/src/CAmRoutingSender.cpp
+++ b/AudioManagerDaemon/src/CAmRoutingSender.cpp
@@ -205,6 +205,7 @@ am_Error_e CAmRoutingSender::asyncAbort(const am_Handle_s& handle)
iter = mMapHandleInterface.find(handle.handle);
if (iter != mMapHandleInterface.end())
{
+ removeHandle(handle);
return (iter->second->asyncAbort(handle));
}
@@ -222,7 +223,15 @@ am_Error_e CAmRoutingSender::asyncConnect(am_Handle_s& handle, const am_connecti
handle = createHandle(handleData, H_CONNECT);
mMapConnectionInterface.insert(std::make_pair(connectionID, iter->second));
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncConnect(handle, connectionID, sourceID, sinkID, connectionFormat));
+ am_Error_e syncError(iter->second->asyncConnect(handle, connectionID, sourceID, sinkID, connectionFormat));
+
+ if (syncError)
+ {
+ removeHandle(handle);
+ removeConnectionLookup(connectionID);
+ }
+ return(syncError);
+
}
return (E_NON_EXISTENT);
@@ -238,8 +247,12 @@ am_Error_e CAmRoutingSender::asyncDisconnect(am_Handle_s& handle, const am_conne
handleData.connectionID = connectionID;
handle = createHandle(handleData, H_DISCONNECT);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- am_Error_e returnVal = iter->second->asyncDisconnect(handle, connectionID);
- return (returnVal);
+ am_Error_e syncError(iter->second->asyncDisconnect(handle, connectionID));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
@@ -256,7 +269,12 @@ am_Error_e CAmRoutingSender::asyncSetSinkVolume(am_Handle_s& handle, const am_si
handleData.volume = volume;
handle = createHandle(handleData, H_SETSINKVOLUME);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncSetSinkVolume(handle, sinkID, volume, ramp, time));
+ am_Error_e syncError(iter->second->asyncSetSinkVolume(handle, sinkID, volume, ramp, time));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -272,7 +290,12 @@ am_Error_e CAmRoutingSender::asyncSetSourceVolume(am_Handle_s& handle, const am_
handleData.volume = volume;
handle = createHandle(handleData, H_SETSOURCEVOLUME);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncSetSourceVolume(handle, sourceID, volume, ramp, time));
+ am_Error_e syncError(iter->second->asyncSetSourceVolume(handle, sourceID, volume, ramp, time));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -288,7 +311,12 @@ am_Error_e CAmRoutingSender::asyncSetSourceState(am_Handle_s& handle, const am_s
handleData.sourceState = state;
handle = createHandle(handleData, H_SETSOURCESTATE);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncSetSourceState(handle, sourceID, state));
+ am_Error_e syncError(iter->second->asyncSetSourceState(handle, sourceID, state));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -304,7 +332,12 @@ am_Error_e CAmRoutingSender::asyncSetSinkSoundProperty(am_Handle_s& handle, cons
handleData.soundPropery = soundProperty;
handle = createHandle(handleData, H_SETSINKSOUNDPROPERTY);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncSetSinkSoundProperty(handle, sinkID, soundProperty));
+ am_Error_e syncError(iter->second->asyncSetSinkSoundProperty(handle, sinkID, soundProperty));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -320,7 +353,12 @@ am_Error_e CAmRoutingSender::asyncSetSourceSoundProperty(am_Handle_s& handle, co
handleData.soundPropery = soundProperty;
handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTY);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncSetSourceSoundProperty(handle, sourceID, soundProperty));
+ am_Error_e syncError(iter->second->asyncSetSourceSoundProperty(handle, sourceID, soundProperty));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -336,7 +374,12 @@ am_Error_e CAmRoutingSender::asyncSetSourceSoundProperties(am_Handle_s& handle,
handleData.soundProperties = new std::vector<am_SoundProperty_s>(listSoundProperties);
handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTIES);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncSetSourceSoundProperties(handle, sourceID, listSoundProperties));
+ am_Error_e syncError(iter->second->asyncSetSourceSoundProperties(handle, sourceID, listSoundProperties));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -352,7 +395,13 @@ am_Error_e CAmRoutingSender::asyncSetSinkSoundProperties(am_Handle_s& handle, co
handleData.soundProperties = new std::vector<am_SoundProperty_s>(listSoundProperties);
handle = createHandle(handleData, H_SETSINKSOUNDPROPERTIES);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncSetSinkSoundProperties(handle, sinkID, listSoundProperties));
+ am_Error_e syncError(iter->second->asyncSetSinkSoundProperties(handle, sinkID, listSoundProperties));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.soundProperties;
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
@@ -369,7 +418,12 @@ am_Error_e CAmRoutingSender::asyncCrossFade(am_Handle_s& handle, const am_crossf
handleData.hotSink = hotSink;
handle = createHandle(handleData, H_CROSSFADE);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
- return (iter->second->asyncCrossFade(handle, crossfaderID, hotSink, rampType, time));
+ am_Error_e syncError(iter->second->asyncCrossFade(handle, crossfaderID, hotSink, rampType, time));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -535,7 +589,6 @@ am_Error_e CAmRoutingSender::removeHandle(const am_Handle_s& handle)
{
if (mlistActiveHandles.erase(handle))
{
- logInfo(__PRETTY_FUNCTION__,handle.handle,handle.handleType);
return (E_OK);
}
logError(__PRETTY_FUNCTION__,"Could not remove handle",handle.handle);
@@ -578,25 +631,18 @@ am_Handle_s CAmRoutingSender::createHandle(const am_handleData_c& handleData, co
* @param handle the handle
* @return a class holding the handle data
*/
-CAmRoutingSender::am_handleData_c CAmRoutingSender::returnHandleData(const am_Handle_s handle) const
+am_Error_e CAmRoutingSender::returnHandleData(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData) const
{
-
HandlesMap::const_iterator it = mlistActiveHandles.begin();
it = mlistActiveHandles.find(handle);
if (it!=mlistActiveHandles.end())
{
- const am_handleData_c & result = it->second;
- logInfo(__PRETTY_FUNCTION__, handle.handle, handle.handleType,
- "connectionID", result.connectionID,
- "sinkID", result.sinkID,
- "sourceID",result.sourceID,
- "sourceState", result.sourceState);
- return result;
+ handleData = it->second;
+ return (am_Error_e::E_OK);
}
- am_handleData_c handleData;
handleData.sinkID=0;
logError(__PRETTY_FUNCTION__,"could not find handle data for handle",handle.handle,handle.handleType);
- return (handleData);
+ return (am_Error_e::E_NON_EXISTENT);
}
void CAmRoutingSender::setRoutingReady()
@@ -681,7 +727,14 @@ am_Error_e CAmRoutingSender::asyncSetVolumes(am_Handle_s& handle, const std::vec
handle = createHandle(handleData, H_SETVOLUMES);
mMapHandleInterface.insert(std::make_pair(+ handle.handle, pRoutingInterface));
- return (pRoutingInterface->asyncSetVolumes(handle, listVolumes));
+ am_Error_e syncError(pRoutingInterface->asyncSetVolumes(handle, listVolumes));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.listVolumes;
+ }
+ return(syncError);
+
}
am_Error_e CAmRoutingSender::asyncSetSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration)
@@ -695,7 +748,13 @@ am_Error_e CAmRoutingSender::asyncSetSinkNotificationConfiguration(am_Handle_s&
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));
+ am_Error_e syncError(iter->second->asyncSetSinkNotificationConfiguration(handle, sinkID,notificationConfiguration));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.notificationConfiguration;
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -711,7 +770,13 @@ am_Error_e CAmRoutingSender::asyncSetSourceNotificationConfiguration(am_Handle_s
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));
+ am_Error_e syncError(iter->second->asyncSetSourceNotificationConfiguration(handle, sourceID,notificationConfiguration));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.notificationConfiguration;
+ }
+ return(syncError);
}
return (E_NON_EXISTENT);
}
@@ -740,4 +805,29 @@ void CAmRoutingSender::getInterfaceVersion(std::string & version) const
{
version = RoutingVersion;
}
+am_Error_e CAmRoutingSender::resyncConnectionState(const am_domainID_t domainID,std::vector<am_Connection_s>& listOfExistingConnections)
+{
+ DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
+ iter = mMapDomainInterface.find(domainID);
+ if (iter != mMapDomainInterface.end())
+ return (iter->second->resyncConnectionState(domainID, listOfExistingConnections));
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::returnHandleDataAndRemove(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData)
+{
+ HandlesMap::const_iterator it = mlistActiveHandles.begin();
+ it = mlistActiveHandles.find(handle);
+ if (it!=mlistActiveHandles.end())
+ {
+ handleData = it->second;
+ mlistActiveHandles.erase(handle);
+ return (am_Error_e::E_OK);
+ }
+ handleData.sinkID=0;
+ logError(__PRETTY_FUNCTION__,"could not find handle data for handle",handle.handle,handle.handleType);
+ return (am_Error_e::E_NON_EXISTENT);
+
+}
+
}
diff --git a/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp b/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp
index ffc493a..9f58a5a 100644
--- a/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp
+++ b/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp
@@ -32,6 +32,17 @@ using namespace testing;
DLT_DECLARE_CONTEXT(AudioManager)
+ACTION(returnResyncConnection)
+{
+ std::vector<am_Connection_s> listConnections;
+ am_Connection_s conn;
+ conn.sinkID=1;
+ conn.sourceID=1;
+ conn.connectionFormat=CF_GENIVI_ANALOG;
+ listConnections.push_back(conn);
+ arg1=listConnections;
+}
+
CAmControlInterfaceTest::CAmControlInterfaceTest() :
pSocketHandler(), //
plistCommandPluginDirs(), //
@@ -306,7 +317,7 @@ TEST_F(CAmControlInterfaceTest,ackDisconnectFailAndRetry)
//then we fire the ack and expect a call on the controlInterface
EXPECT_CALL(pMockControlInterface,cbAckDisconnect(_,E_NON_EXISTENT)).Times(1);
- pRoutingReceiver.ackDisconnect(handle, connectionID, E_NON_EXISTENT);
+ pRoutingReceiver.ackDisconnect(handle, connectionID+1, E_NON_EXISTENT);
//make sure the handle is gone
ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
@@ -588,6 +599,61 @@ TEST_F(CAmControlInterfaceTest,crossFading)
//todo: implement crossfading test
}
+TEST_F(CAmControlInterfaceTest,resyncConnectionsTest)
+{
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+
+ //prepare the scene
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+
+ std::vector<am_Connection_s> listConnections;
+
+ EXPECT_CALL(pMockRoutingInterface,resyncConnectionState(domainID,_)).WillOnce(DoAll(returnResyncConnection(), Return(E_OK)));
+ ASSERT_EQ(am_Error_e::E_OK,pControlReceiver.resyncConnectionState(domainID,listConnections));
+ ASSERT_EQ(listConnections[0].sinkID,1);
+ ASSERT_EQ(listConnections[0].sourceID,1);
+ ASSERT_EQ(listConnections[0].connectionFormat,CF_GENIVI_ANALOG);
+}
+
+TEST_F(CAmControlInterfaceTest,ackConnectNotPossible)
+{
+ am_connectionID_t connectionID;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Connection_s> connectionList;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+
+ //prepare the stage
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //when asyncConnect is called, we expect a call on the routingInterface
+ EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_GENIVI_STEREO)).WillOnce(Return(E_COMMUNICATION));
+ ASSERT_EQ(E_COMMUNICATION, pControlReceiver.connect(handle,connectionID,CF_GENIVI_STEREO,2,2));
+
+ //The list of handles shall be empty
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(connectionList.empty());
+
+}
+
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
diff --git a/AudioManagerDaemon/test/MockIAmRoutingSend.h b/AudioManagerDaemon/test/MockIAmRoutingSend.h
index e16235b..748e64e 100644
--- a/AudioManagerDaemon/test/MockIAmRoutingSend.h
+++ b/AudioManagerDaemon/test/MockIAmRoutingSend.h
@@ -71,6 +71,9 @@ class MockIAmRoutingSend : public IAmRoutingSend {
am_Error_e(const am_Handle_s handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration));
MOCK_METHOD3(asyncSetSourceNotificationConfiguration,
am_Error_e(const am_Handle_s handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration));
+ MOCK_METHOD2(resyncConnectionState,
+ am_Error_e(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections));
+
};
diff --git a/include/IAmControl.h b/include/IAmControl.h
index 8220728..53526fe 100644
--- a/include/IAmControl.h
+++ b/include/IAmControl.h
@@ -32,7 +32,7 @@ class CAmSocketHandler;
#include "audiomanagertypes.h"
-#define ControlVersion "4.0"
+#define ControlVersion "5.0"
namespace am {
/**
@@ -639,6 +639,11 @@ public:
* @return E_OK when successful, E_DATABASE on error
*/
virtual am_Error_e getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const =0;
+ /**
+ * Retrieves a list of all current active connections from a domain. This method
+ * is meant to be used if the audiomanager and a remote domain are out of sync.
+ */
+ virtual am_Error_e resyncConnectionState(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections) =0;
};
diff --git a/include/IAmRouting.h b/include/IAmRouting.h
index 14f1146..1acaac6 100644
--- a/include/IAmRouting.h
+++ b/include/IAmRouting.h
@@ -35,7 +35,7 @@ class CAmSocketHandler;
#include "audiomanagertypes.h"
-#define RoutingVersion "4.0"
+#define RoutingVersion "5.0"
namespace am {
/**
@@ -482,6 +482,11 @@ public:
* @return E_OK on success, E_UNKNOWN on error.
*/
virtual am_Error_e asyncSetSourceNotificationConfiguration(const am_Handle_s handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration) =0;
+ /**
+ * Retrieves a list of all current active connections from a domain. This method
+ * is meant to be used if the audiomanager and a remote domain are out of sync.
+ */
+ virtual am_Error_e resyncConnectionState(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections) =0;
};
}
diff --git a/include/audiomanagertypes.h b/include/audiomanagertypes.h
index aeb802d..d60e2a3 100755
--- a/include/audiomanagertypes.h
+++ b/include/audiomanagertypes.h
@@ -20,8 +20,8 @@
* THIS CODE HAS BEEN GENERATED BY ENTERPRISE ARCHITECT GENIVI MODEL.
* PLEASE CHANGE ONLY IN ENTERPRISE ARCHITECT AND GENERATE AGAIN.
*/
-#if !defined(EA_95D3C82A_0870_4fe0_A468_5AFF99D80A26__INCLUDED_)
-#define EA_95D3C82A_0870_4fe0_A468_5AFF99D80A26__INCLUDED_
+#if !defined(EA_E0F066FD_E6D8_4ca9_84C3_D0C02AF09BF8__INCLUDED_)
+#define EA_E0F066FD_E6D8_4ca9_84C3_D0C02AF09BF8__INCLUDED_
#include <stdint.h>
#include <string>
@@ -372,6 +372,10 @@ enum am_Error_e
* capabilities of a source or a sink or gateway compatibilities for example
*/
E_WRONG_FORMAT = 10,
+ /**
+ * A communication error happened
+ */
+ E_COMMUNICATION = 11,
E_MAX
};
@@ -1461,4 +1465,4 @@ public:
};
}
-#endif // !defined(EA_95D3C82A_0870_4fe0_A468_5AFF99D80A26__INCLUDED_)
+#endif // !defined(EA_E0F066FD_E6D8_4ca9_84C3_D0C02AF09BF8__INCLUDED_)