From 6f2990511f9715fe5fb0b1eb2e3339d8037bbba7 Mon Sep 17 00:00:00 2001
From: Wenpeng Song <wenpeng.song@iopsys.eu>
Date: Fri, 22 Sep 2023 16:51:04 +0200
Subject: [PATCH] correction of ast_control_pvt_cause indication

---
 channels/chan_brcm.c | 83 +++++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 40 deletions(-)

diff --git a/channels/chan_brcm.c b/channels/chan_brcm.c
index dd7ccc73ad..162a563f46 100644
--- a/channels/chan_brcm.c
+++ b/channels/chan_brcm.c
@@ -966,44 +966,7 @@ static int brcm_indicate(struct ast_channel *ast, int condition, const void *dat
 		pvt_unlock(sub->parent);
 		break;
 	case AST_CONTROL_PVT_CAUSE_CODE:
-		pvt_lock(sub->parent, "indicate");
-		const struct ast_control_pvt_cause_code *cause_code = data;
-		int ast_cause = cause_code->ast_cause;
-		ast_debug(2, "AST_CONTROL_PVT_CAUSE_CODE = %d, chan_name = %s\n", ast_cause, cause_code->chan_name);
-
-		switch (ast_cause) {
-		case AST_CAUSE_NO_USER_RESPONSE:
-		case AST_CAUSE_NO_ANSWER:
-		case AST_CAUSE_CALL_REJECTED:
-			endpt_signal(sub->parent->line_id, "ringback", "off", NULL);
-			if (ast_channel_state(ast) != AST_STATE_UP) {
-				endpt_signal(sub->parent->line_id, "congestion", "on", NULL);
-                                strncpy(sub->parent->extensionCallStatus, "Disconnected", CALL_STATUS_MAX_LEN);
-				break;
-			}
-			res = -1;
-			break;
-		  case AST_CAUSE_NORMAL_CLEARING:
-			// This is just fine.
-			break;
-		  case AST_CAUSE_USER_BUSY:
-			endpt_signal(sub->parent->line_id, "ringback", "off", NULL);
-			if (ast_channel_state(ast) != AST_STATE_UP) {
-				/* XXX We should play a busy tone here!! */
-                                sub->channel_state = CALLENDED;
-				endpt_signal(sub->parent->line_id, "busy", "on", NULL);
-				strncpy(sub->parent->extensionCallStatus, "Disconnected", CALL_STATUS_MAX_LEN);
-				break;
-			}
-			res = -1;
-		  case AST_CAUSE_NETWORK_OUT_OF_ORDER:
-			brcm_stop_dialtone(sub->parent); // stop any dialtone exist if disconnection happened due to network/server
-			break;
-		  default:
-			ast_debug(1, "Don't know how to handle cause code %d\n", ast_cause);
-			break;
-		}
-		pvt_unlock(sub->parent);
+		ast_debug(4, "ignore indication for AST_CONTROL_PVT_CAUSE_CODE = %d, chan_name = %s\n", ast_cause, cause_code->chan_name);
 		break;
 	default:
 		res = -1;
@@ -1364,6 +1327,41 @@ static int brcm_hangup(struct ast_channel *ast)
 
 	p = sub->parent;
 	pvt_lock(p, "TELCHAN hangup");
+
+	if (ast_channel_hangupcause(ast)){
+		ast_log(LOG_NOTICE, "CAUSE_CODE = %d", ast_channel_hangupcause(ast));
+
+		switch (ast_channel_hangupcause(ast)) {
+		case AST_CAUSE_NO_USER_RESPONSE:
+		case AST_CAUSE_NO_ANSWER:
+		case AST_CAUSE_CALL_REJECTED:
+			endpt_signal(sub->parent->line_id, "ringback", "off", NULL);
+			if (ast_channel_state(ast) != AST_STATE_UP) {
+				endpt_signal(sub->parent->line_id, "congestion", "on", NULL);
+				strncpy(sub->parent->extensionCallStatus, "Disconnected", CALL_STATUS_MAX_LEN);
+				p->dialtone = DIALTONE_CONGESTION;
+				break;
+			}
+			break;
+		case AST_CAUSE_NORMAL_CLEARING:
+			// This is just fine.
+			break;
+		case AST_CAUSE_USER_BUSY:
+			endpt_signal(sub->parent->line_id, "ringback", "off", NULL);
+			if (ast_channel_state(ast) != AST_STATE_UP) {
+				/* XXX We should play a busy tone here!! */
+				sub->channel_state = CALLENDED;
+				endpt_signal(sub->parent->line_id, "busy", "on", NULL);
+				strncpy(sub->parent->extensionCallStatus, "Disconnected", CALL_STATUS_MAX_LEN);
+				p->dialtone = DIALTONE_CONGESTION;
+				break;
+			}
+		case AST_CAUSE_NETWORK_OUT_OF_ORDER:
+			brcm_stop_dialtone(sub->parent); // stop any dialtone exist if disconnection happened due to network/server
+			break;
+		}
+	}
+
 	sub_peer = brcm_subchannel_get_peer(sub);
 
 	ast_log(LOG_NOTICE, "brcm_hangup chan=%s line_id=%d connection_id=%d dialtone=%s channel_state=%s peer_state=%s sub_timer: %d, peer_timer: %d\n",
@@ -1503,8 +1501,12 @@ static int brcm_hangup(struct ast_channel *ast)
 	/* Check for channel state before dial tone timeout */
 	if(sub->channel_state == CALLENDED && sub_peer->channel_state != INCALL) {
 		/* If we hangup but not playing howler, start playing timeout tones */
-		p->dialtone = DIALTONE_ON;
-		handle_dialtone_timeout(p);
+		if(p->dialtone == DIALTONE_CONGESTION){
+			p->dialtone_timeout_timer_id = ast_sched_add(sched, channel_config[p->line_id].dialtone_timeoutmsec, handle_dialtone_timeout, p);
+		} else {
+			p->dialtone = DIALTONE_ON;
+			handle_dialtone_timeout(p);
+		}
 	}
 
 	/* Clear un-answered call */
@@ -2298,6 +2300,7 @@ static int handle_dialtone_timeout(const void *data)
 
 		switch (p->dialtone) {
 			case DIALTONE_ON:
+			case DIALTONE_CONGESTION:
 				p->dialtone = DIALTONE_UNOBTAINABLE;
 				p->dialtone_timeout_timer_id = ast_sched_add(sched, s->offhook_nu_timeoutmsec, handle_dialtone_timeout, p);
 				break;
-- 
GitLab