pal: Update StreamNonTunnel to support SSR/PDR
Propagate SSR/PDR error to NT mode clients via a callback.
Change-Id: I137573b7b2a1f3111e86e20a1c534d8442755083
diff --git a/stream/inc/Stream.h b/stream/inc/Stream.h
index 69bc345..6584975 100644
--- a/stream/inc/Stream.h
+++ b/stream/inc/Stream.h
@@ -255,6 +255,9 @@
int32_t setECRef_l(std::shared_ptr<Device> dev __unused, bool is_enable __unused) {return 0;};
int32_t ssrDownHandler() override;
int32_t ssrUpHandler() override;
+private:
+ /*This notifies that the system went through/is in a ssr*/
+ bool ssrInNTMode;
};
#endif//STREAM_H_
diff --git a/stream/src/StreamNonTunnel.cpp b/stream/src/StreamNonTunnel.cpp
index 4e0aac2..1ad47f1 100644
--- a/stream/src/StreamNonTunnel.cpp
+++ b/stream/src/StreamNonTunnel.cpp
@@ -75,6 +75,7 @@
outMaxMetadataSz = 0;
mDevices.clear();
currentState = STREAM_IDLE;
+ ssrInNTMode = false;
//Modify cached values only at time of SSR down.
cachedState = STREAM_IDLE;
@@ -137,10 +138,10 @@
int32_t status = 0;
mStreamMutex.lock();
- if (rm->cardState == CARD_STATUS_OFFLINE) {
+ if (rm->cardState == CARD_STATUS_OFFLINE || ssrInNTMode == true) {
PAL_ERR(LOG_TAG, "Sound card offline, can not open stream");
usleep(SSR_RECOVERY);
- status = -EIO;
+ status = -ENETRESET;
goto exit;
}
@@ -170,7 +171,6 @@
return status;
}
-//TBD: move this to Stream, why duplicate code?
int32_t StreamNonTunnel::close()
{
int32_t status = 0;
@@ -180,13 +180,6 @@
session, currentState);
if (currentState == STREAM_IDLE) {
- /* If current state is STREAM_IDLE, that means :
- * 1. SSR down has happened
- * Session is already closed as part of ssr handling, so just
- * close device and destroy the objects.
- * 2. Stream created but opened failed.
- * No need to call session close for this case too.
- */
PAL_VERBOSE(LOG_TAG, "closed the devices successfully");
goto exit;
} else if (currentState == STREAM_STARTED || currentState == STREAM_PAUSED) {
@@ -195,9 +188,7 @@
PAL_ERR(LOG_TAG, "stream stop failed. status %d", status);
}
- rm->lockGraph();
status = session->close(this);
- rm->unlockGraph();
if (0 != status) {
PAL_ERR(LOG_TAG, "session close failed with status %d", status);
}
@@ -219,10 +210,10 @@
{
int32_t status = 0;
mStreamMutex.lock();
- if (rm->cardState == CARD_STATUS_OFFLINE) {
- cachedState = STREAM_STARTED;
- PAL_ERR(LOG_TAG, "Sound card offline. Update the cached state %d",
- cachedState);
+ if (rm->cardState == CARD_STATUS_OFFLINE || ssrInNTMode == true) {
+ PAL_ERR(LOG_TAG, "Sound card offline currentState %d",
+ currentState);
+ status = -ENETRESET;
goto exit;
}
@@ -230,33 +221,27 @@
session, mStreamAttr->direction, currentState);
if (currentState == STREAM_INIT || currentState == STREAM_STOPPED) {
- rm->lockGraph();
status = session->prepare(this);
if (0 != status) {
PAL_ERR(LOG_TAG, "Rx session prepare is failed with status %d",
status);
- rm->unlockGraph();
goto exit;
}
PAL_VERBOSE(LOG_TAG, "session prepare successful");
status = session->start(this);
- if (errno == -ENETRESET &&
+ if (status == -ENETRESET &&
rm->cardState != CARD_STATUS_OFFLINE) {
PAL_ERR(LOG_TAG, "Sound card offline, informing RM");
rm->ssrHandler(CARD_STATUS_OFFLINE);
- cachedState = STREAM_STARTED;
- rm->unlockGraph();
goto exit;
}
if (0 != status) {
PAL_ERR(LOG_TAG, "Rx session start is failed with status %d",
status);
- rm->unlockGraph();
goto exit;
}
PAL_VERBOSE(LOG_TAG, "session start successful");
- rm->unlockGraph();
currentState = STREAM_STARTED;
} else if (currentState == STREAM_STARTED) {
PAL_INFO(LOG_TAG, "Stream already started, state %d", currentState);
@@ -279,7 +264,7 @@
int32_t status = 0;
mStreamMutex.lock();
- PAL_ERR(LOG_TAG, "Enter. session handle - %pK mStreamAttr->direction - %d state %d",
+ PAL_DBG(LOG_TAG, "Enter. session handle - %pK mStreamAttr->direction - %d state %d",
session, mStreamAttr->direction, currentState);
if (currentState == STREAM_STARTED || currentState == STREAM_PAUSED) {
@@ -312,6 +297,15 @@
PAL_DBG(LOG_TAG, "Enter. session handle - %pK", session);
mStreamMutex.lock();
+
+ if ((rm->cardState == CARD_STATUS_OFFLINE)
+ || ssrInNTMode == true) {
+ PAL_ERR(LOG_TAG, "Sound card offline currentState %d",
+ currentState);
+ mStreamMutex.unlock();
+ return -ENETRESET;
+ }
+
status = session->prepare(this);
if (0 != status)
PAL_ERR(LOG_TAG, "session prepare failed with status = %d", status);
@@ -328,25 +322,10 @@
PAL_DBG(LOG_TAG, "Enter. session handle - %pK, state %d",
session, currentState);
- if ((rm->cardState == CARD_STATUS_OFFLINE) || cachedState != STREAM_IDLE) {
- /* calculate sleep time based on buf->size, sleep and return buf->size */
- uint32_t streamSize;
- uint32_t byteWidth = mStreamAttr->in_media_config.bit_width / 8;
- uint32_t sampleRate = mStreamAttr->in_media_config.sample_rate;
- struct pal_channel_info chInfo = mStreamAttr->in_media_config.ch_info;
-
- streamSize = byteWidth * chInfo.channels;
- if ((streamSize == 0) || (sampleRate == 0)) {
- PAL_ERR(LOG_TAG, "stream_size= %d, srate = %d",
- streamSize, sampleRate);
- status = -EINVAL;
- goto exit;
- }
- size = buf->size;
- memset(buf->buffer, 0, size);
- usleep((uint64_t)size * 1000000 / streamSize / sampleRate);
- PAL_DBG(LOG_TAG, "Sound card offline, dropped buffer size - %d", size);
- status = size;
+ if ((rm->cardState == CARD_STATUS_OFFLINE) || ssrInNTMode == true) {
+ PAL_ERR(LOG_TAG, "Sound card offline currentState %d",
+ currentState);
+ status = -ENETRESET;
goto exit;
}
@@ -354,21 +333,18 @@
status = session->read(this, SHMEM_ENDPOINT, buf, &size);
if (0 != status) {
PAL_ERR(LOG_TAG, "session read is failed with status %d", status);
- if (errno == -ENETRESET &&
+ if (status == -ENETRESET &&
rm->cardState != CARD_STATUS_OFFLINE) {
PAL_ERR(LOG_TAG, "Sound card offline, informing RM");
rm->ssrHandler(CARD_STATUS_OFFLINE);
size = buf->size;
- status = size;
PAL_DBG(LOG_TAG, "dropped buffer size - %d", size);
goto exit;
} else if (rm->cardState == CARD_STATUS_OFFLINE) {
size = buf->size;
- status = size;
PAL_DBG(LOG_TAG, "dropped buffer size - %d", size);
goto exit;
} else {
- status = errno;
goto exit;
}
}
@@ -388,10 +364,6 @@
{
int32_t status = 0;
int32_t size = 0;
- uint32_t frameSize = 0;
- uint32_t byteWidth = 0;
- uint32_t sampleRate = 0;
- uint32_t channelCount = 0;
PAL_DBG(LOG_TAG, "Enter. session handle - %pK, state %d",
session, currentState);
@@ -400,22 +372,11 @@
// If cached state is not STREAM_IDLE, we are still processing SSR up.
if ((rm->cardState == CARD_STATUS_OFFLINE)
- || cachedState != STREAM_IDLE) {
- byteWidth = mStreamAttr->out_media_config.bit_width / 8;
- sampleRate = mStreamAttr->out_media_config.sample_rate;
- channelCount = mStreamAttr->out_media_config.ch_info.channels;
-
- frameSize = byteWidth * channelCount;
- if ((frameSize == 0) || (sampleRate == 0)) {
- PAL_ERR(LOG_TAG, "frameSize=%d, sampleRate=%d", frameSize, sampleRate);
- mStreamMutex.unlock();
- return -EINVAL;
- }
+ || ssrInNTMode == true) {
size = buf->size;
- usleep((uint64_t)size * 1000000 / frameSize / sampleRate);
- PAL_DBG(LOG_TAG, "dropped buffer size - %d", size);
+ PAL_DBG(LOG_TAG, "sound card offline dropped buffer size - %d", size);
mStreamMutex.unlock();
- return size;
+ return -ENETRESET;
}
mStreamMutex.unlock();
@@ -425,21 +386,18 @@
PAL_ERR(LOG_TAG, "session write is failed with status %d", status);
/* ENETRESET is the error code returned by AGM during SSR */
- if (errno == -ENETRESET &&
+ if (status == -ENETRESET &&
rm->cardState != CARD_STATUS_OFFLINE) {
PAL_ERR(LOG_TAG, "Sound card offline, informing RM");
rm->ssrHandler(CARD_STATUS_OFFLINE);
size = buf->size;
- status = size;
PAL_DBG(LOG_TAG, "dropped buffer size - %d", size);
goto exit;
} else if (rm->cardState == CARD_STATUS_OFFLINE) {
size = buf->size;
- status = size;
PAL_DBG(LOG_TAG, "dropped buffer size - %d", size);
goto exit;
} else {
- status = errno;
goto exit;
}
}
@@ -503,9 +461,16 @@
goto error;
}
+ mStreamMutex.lock();
+ if ((rm->cardState == CARD_STATUS_OFFLINE) || ssrInNTMode == true) {
+ PAL_ERR(LOG_TAG, "Sound card offline currentState %d",
+ currentState);
+ status = -ENETRESET;
+ goto error;
+ }
+
PAL_DBG(LOG_TAG, "start, set parameter %u, session handle - %p", param_id, session);
- mStreamMutex.lock();
// Stream may not know about tags, so use setParameters instead of setConfig
switch (param_id) {
case PAL_PARAM_ID_MODULE_CONFIG:
@@ -517,15 +482,20 @@
break;
}
+error:
mStreamMutex.unlock();
PAL_VERBOSE(LOG_TAG, "exit, session parameter %u set with status %d", param_id, status);
-error:
return status;
}
int32_t StreamNonTunnel::drain(pal_drain_type_t type)
{
PAL_ERR(LOG_TAG, "drain");
+ if ((rm->cardState == CARD_STATUS_OFFLINE) || ssrInNTMode == true) {
+ PAL_ERR(LOG_TAG, "Sound card offline currentState %d",
+ currentState);
+ return -ENETRESET;
+ }
return session->drain(type);
}
@@ -546,10 +516,17 @@
int32_t status = 0;
mStreamMutex.lock();
+ if ((rm->cardState == CARD_STATUS_OFFLINE) || ssrInNTMode == true) {
+ PAL_ERR(LOG_TAG, "Sound card offline currentState %d",
+ currentState);
+ status = -ENETRESET;
+ goto exit;
+ }
status = session->flush();
- mStreamMutex.unlock();
+exit:
+ mStreamMutex.unlock();
return status;
}
@@ -619,101 +596,28 @@
{
int status = 0;
+
mStreamMutex.lock();
- /* Updating cached state here only if it's STREAM_IDLE,
- * Otherwise we can assume it is updated by hal thread
- * already.
+ /* In NonTunnelMode once SSR happens, that session is not reusuable
+ * Hence set the ssr to true and return all subsequent calls with
+ * -ENETRESET, untill the client sets up a new session.
+ *
*/
- if (cachedState == STREAM_IDLE)
- cachedState = currentState;
- PAL_DBG(LOG_TAG, "Enter. session handle - %pK cached State %d",
- session, cachedState);
+ PAL_DBG(LOG_TAG, "Enter. session handle - %pK currentState State %d",
+ session, currentState);
- if (currentState == STREAM_INIT || currentState == STREAM_STOPPED) {
- //Not calling stream close here, as we don't want to delete the session
- //and device objects.
- rm->lockGraph();
- status = session->close(this);
- rm->unlockGraph();
- currentState = STREAM_IDLE;
- mStreamMutex.unlock();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "session close failed. status %d", status);
- goto exit;
- }
- } else if (currentState == STREAM_STARTED || currentState == STREAM_PAUSED) {
- mStreamMutex.unlock();
- status = stop();
- if (0 != status)
- PAL_ERR(LOG_TAG, "stream stop failed. status %d", status);
- mStreamMutex.lock();
- rm->lockGraph();
- status = session->close(this);
- rm->unlockGraph();
- currentState = STREAM_IDLE;
- mStreamMutex.unlock();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "session close failed. status %d", status);
- goto exit;
- }
- } else {
- PAL_ERR(LOG_TAG, "stream state is %d, nothing to handle", currentState);
- mStreamMutex.unlock();
- goto exit;
- }
+ ssrInNTMode = true;
+ if (streamCb)
+ streamCb(reinterpret_cast<pal_stream_handle_t *>(this), PAL_STREAM_CBK_EVENT_ERROR, NULL, 0, this->cookie);
-exit :
+ mStreamMutex.unlock();
+
PAL_DBG(LOG_TAG, "Exit, status %d", status);
return status;
}
int32_t StreamNonTunnel::ssrUpHandler()
{
- int status = 0;
-
- PAL_DBG(LOG_TAG, "Enter. session handle - %pK state %d",
- session, cachedState);
-
- if (cachedState == STREAM_INIT) {
- status = open();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "stream open failed. status %d", status);
- goto exit;
- }
- } else if (cachedState == STREAM_STARTED) {
- status = open();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "stream open failed. status %d", status);
- goto exit;
- }
- status = start();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "stream start failed. status %d", status);
- goto exit;
- }
- } else if (cachedState == STREAM_PAUSED) {
- status = open();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "stream open failed. status %d", status);
- goto exit;
- }
- status = start();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "stream start failed. status %d", status);
- goto exit;
- }
- status = pause();
- if (0 != status) {
- PAL_ERR(LOG_TAG, "stream set pause failed. status %d", status);
- goto exit;
- }
- } else {
- PAL_ERR(LOG_TAG, "stream not in correct state to handle %d", cachedState);
- goto exit;
- }
-exit :
- cachedState = STREAM_IDLE;
- PAL_DBG(LOG_TAG, "Exit, status %d", status);
- return status;
+ return 0;
}