From f4d3f021f953d1e91d5c1c081fe6ba604b084b6d Mon Sep 17 00:00:00 2001
From: Andre Barbosa <andre.emanuel.barbosa@gmail.com>
Date: Tue, 29 Jun 2021 17:07:44 +0100
Subject: [PATCH] res_stasis_playback: Check for chan hangup on
 play_on_channels

Verify `ast_check_hangup` before looping to the next sound file.
If the call is already hangup we just break the cycle.
It also ensures that the PlaybackFinished event is sent if the call was hangup.

This is also use-full when we are playing a big list of file for a channel that is hangup.
Before this patch Asterisk will give a warning for every sound not played and fire a PlaybackStart for every sound file on the list tried to be played.

With the patch we just break the playback cycle when the chan is hangup.

ASTERISK-29501 #close

Change-Id: Ic4e1c01b974c9a1f2d9678c9d6b380bcfc69feb8
---
 res/res_stasis_playback.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/res/res_stasis_playback.c b/res/res_stasis_playback.c
index 2013bb717a..d558e18345 100644
--- a/res/res_stasis_playback.c
+++ b/res/res_stasis_playback.c
@@ -261,13 +261,13 @@ static int playback_first_update(struct stasis_app_playback *playback,
 }
 
 static void playback_final_update(struct stasis_app_playback *playback,
-	long playedms, int res, const char *uniqueid)
+	long playedms, int res, int hangup, const char *uniqueid)
 {
 	SCOPED_AO2LOCK(lock, playback);
 
 	playback->playedms = playedms;
 	if (res == 0) {
-		if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1) {
+		if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1 || hangup ) {
 			playback->state = STASIS_PLAYBACK_STATE_COMPLETE;
 		} else {
 			playback->state = STASIS_PLAYBACK_STATE_CONTINUING;
@@ -279,7 +279,7 @@ static void playback_final_update(struct stasis_app_playback *playback,
 		} else {
 			ast_log(LOG_WARNING, "%s: Playback failed for %s\n",
 				uniqueid, playback->media);
-			if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1) {
+			if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1 || hangup ) {
 				playback->state = STASIS_PLAYBACK_STATE_FAILED;
 			} else {
 				playback->state = STASIS_PLAYBACK_STATE_CONTINUING;
@@ -294,6 +294,7 @@ static void play_on_channel(struct stasis_app_playback *playback,
 	struct ast_channel *chan)
 {
 	int res;
+	int hangup;
 	long offsetms;
 	size_t index;
 
@@ -377,8 +378,16 @@ static void play_on_channel(struct stasis_app_playback *playback,
 			continue;
 		}
 
-		playback_final_update(playback, offsetms, res,
+		hangup = ast_check_hangup(chan);
+
+		playback_final_update(playback, offsetms, res, hangup,
 			ast_channel_uniqueid(chan));
+
+		if (hangup) {
+			ast_log(LOG_DEBUG, "Channel: %s already hangup, stop playback\n", ast_channel_name(chan));
+			break;
+		}
+
 		if (res == AST_CONTROL_STREAM_STOP) {
 			break;
 		}
-- 
GitLab