diff --git a/channels/chan_brcm.c b/channels/chan_brcm.c
index 62512be18ca29ce7e1c70e75f3ecc87f64acf94a..9d25422c2992686cff15e25ac33c108cc2dad029 100644
--- a/channels/chan_brcm.c
+++ b/channels/chan_brcm.c
@@ -899,50 +899,52 @@ static int brcm_call(struct ast_channel *chan, const char *dest, int timeout)
 static int brcm_hangup(struct ast_channel *ast)
 {
 	struct brcm_pvt *p;
-	struct brcm_subchannel *sub, *sub_peer;
+	struct brcm_subchannel *sub = ast_channel_tech_pvt(ast), *sub_peer;
 	struct ast_channel *peer_owner;
-	sub = ast_channel_tech_pvt(ast);
 	int conf_timer_removed = 0;
 
-	if (!ast_channel_tech_pvt(ast)) {
+	if (!sub) {
 		ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
 		return 0;
 	}
-	pvt_lock(sub->parent, "TELCHAN hangup");
-	p = sub->parent;
 
-        sub_peer = brcm_subchannel_get_peer(sub);
-        /*If call is not connected (INCALL state )/ Call is dialing but Subchannel is busy move to Disconnected state */
-        if((sub->channel_state!= ONHOOK && sub_peer->channel_state != OFFHOOK))
-        {
-            //Ignore state change if we are INCALL
-            if(sub->channel_state != INCALL && sub_peer->channel_state != INCALL)
-            {
-              /*Cases where other party doesnt picksup call ,after timeout move it to idle status */
-              if(sub->channel_state == RINGING && sub_peer->channel_state == ONHOOK)
-                strncpy(p->callStatus, "Idle", CALL_STATUS_MAX_LEN);
-              else
-		strncpy(p->callStatus, "Disconnected", CALL_STATUS_MAX_LEN);
-            }
-        }
+	p = sub->parent;
+	pvt_lock(p, "TELCHAN hangup");
+	sub_peer = brcm_subchannel_get_peer(sub);
 
-	ast_debug(1, "brcm_hangup(%s) line_id=%d connection_id=%d dialtone=%s channel_state=%s\n",
+	ast_debug(1, "%s(%s): line_id=%d connection_id=%d dialtone=%s channel_state=%s, peer_state=%s\n", __func__,
 		ast_channel_name(ast), p->line_id, sub->connection_id, dialtone_map[p->dialtone].str,
-		state2str(sub->channel_state));
-        if(sub_peer->conf_timer_id != -1){
-            conf_timer_removed = 1;
-            if (ast_sched_del(sched, sub_peer->conf_timer_id)) {
-                ast_log(LOG_WARNING, "Failed to remove scheduled conference setup timer\n");
-            }
-        sub_peer->conf_timer_id = -1;
-        }
-        if(sub->conf_timer_id != -1){
-            conf_timer_removed = 1;
-            if (ast_sched_del(sched, sub->conf_timer_id)) {
-                ast_log(LOG_WARNING, "Failed to remove scheduled conference setup timer\n");
-            }
-        sub->conf_timer_id = -1;
-        }
+		state2str(sub->channel_state), state2str(sub_peer->channel_state));
+
+	/* If call is not connected (INCALL) or is dialing but Subchannel is busy, move to Disconnected state */
+	if ((sub->channel_state!= ONHOOK && sub_peer->channel_state != OFFHOOK))
+	{
+		//Ignore state change if we are INCALL
+		if(sub->channel_state != INCALL && sub_peer->channel_state != INCALL)
+		{
+		  /*Cases where other party doesnt picksup call ,after timeout move it to idle status */
+		  if(sub->channel_state == RINGING && sub_peer->channel_state == ONHOOK)
+			  strncpy(p->callStatus, "Idle", CALL_STATUS_MAX_LEN);
+		  else
+			  strncpy(p->callStatus, "Disconnected", CALL_STATUS_MAX_LEN);
+		}
+	}
+
+	if (sub_peer->conf_timer_id != -1) {
+		conf_timer_removed = 1;
+		if (ast_sched_del(sched, sub_peer->conf_timer_id)) {
+			ast_log(LOG_WARNING, "Failed to remove scheduled conference setup timer\n");
+		}
+		sub_peer->conf_timer_id = -1;
+	}
+
+	if (sub->conf_timer_id != -1){
+		conf_timer_removed = 1;
+		if (ast_sched_del(sched, sub->conf_timer_id)) {
+			ast_log(LOG_WARNING, "Failed to remove scheduled conference setup timer\n");
+		}
+		sub->conf_timer_id = -1;
+	}
 
 	if (sub->channel_state == CALLWAITING) {
 		brcm_stop_callwaiting(p);
@@ -958,7 +960,8 @@ static int brcm_hangup(struct ast_channel *ast)
 			p->tech->stop_ringing_callerid_pending(p);
 		}
 	} else if (brcm_subchannel_is_idle(sub_peer) && p->tech->release) {
-		//No active subchannel left, release
+		// No active subchannel left, release
+		ast_debug(1, "Release the call since the peer sub-channel is also idle\n");
 		p->tech->release(p);
 	}
 
@@ -994,23 +997,23 @@ static int brcm_hangup(struct ast_channel *ast)
 	 * Additional check for ONHOOK channel state so that handle_dialtone_timeout()
 	 * isn't called again when going on-hook
 	 */
-	if(p->dialtone != DIALTONE_HOWLER && sub->channel_state != ONHOOK) {
-		ast_debug(6, "Setting channel state to %s\n", state2str(sub->channel_state));
+	if (p->dialtone != DIALTONE_HOWLER && sub->channel_state != ONHOOK) {
 		/*In case the call ends before connecting ,move the party to ONHOOK state Since its already on ONHOOK ,
 		we never get on ONHOOK event again*/
 		if (sub->channel_state == RINGING)
 			sub->channel_state = ONHOOK;
 		else
 			sub->channel_state = CALLENDED;
+		ast_debug(6, "Setting channel state to %s\n", state2str(sub->channel_state));
 	}
 
-	if ( sub->conference_initiator && brcm_in_conference(p)) {
+	if (sub->conference_initiator && brcm_in_conference(p)) {
 		/* Switch still active call leg out of conference mode */
 		brcm_stop_conference(sub);
 		brcm_stop_conference(sub_peer);
 	}
 
-	if(sub_peer->channel_state == INCALL && conf_timer_removed== 1) {
+	if (sub_peer->channel_state == INCALL && conf_timer_removed == 1) {
 		ast_log(LOG_NOTICE,"In case some party hangs up ,Unhold the other parties \n");
 		pvt_lock(sub_peer->parent, "Brcm Hangup");
 		if(sub_peer->owner)
@@ -1033,7 +1036,7 @@ static int brcm_hangup(struct ast_channel *ast)
 	ast_channel_tech_pvt_set(ast, NULL);
 	brcm_close_connection(sub);
 
-        /*Check for channelstate before dialtone timeout */
+	/* 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;
@@ -2708,13 +2711,36 @@ static void brcm_assign_line_id(struct brcm_pvt *p)
 	}
 }
 
+static int brcm_in_dialing(const struct brcm_pvt *p)
+{
+	int i;
+	for (i=0; i<NUM_SUBCHANNELS; i++) {
+		if (p->sub[i]->channel_state == DIALING) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int brcm_in_ringback(const struct brcm_pvt *p)
+{
+	int i;
+	for (i=0; i<NUM_SUBCHANNELS; i++) {
+		if (p->sub[i]->channel_state == RINGBACK) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
 
 static int brcm_in_call(const struct brcm_pvt *p)
 {
 	int i;
 	for (i=0; i<NUM_SUBCHANNELS; i++) {
 		if (p->sub[i]->channel_state == INCALL) {
-                    return 1;
+			return 1;
 		}
 	}
 
@@ -2759,7 +2785,6 @@ static int brcm_in_onhold(const struct brcm_pvt *p)
 
 static int brcm_in_conference(const struct brcm_pvt *p)
 {
-
 	return (p->sub[0]->channel_state == INCALL && 
 		p->sub[1]->channel_state == INCALL) ||
 		p->sub[0]->conference_initiator ||
@@ -3987,7 +4012,7 @@ static int brcm_signal_callwaiting(const struct brcm_pvt *p)
 static int brcm_stop_callwaiting(const struct brcm_pvt *p)
 {
 	endpt_signal(p->line_id, "callwt", "off", NULL);
-	brcm_send_ubus_event("CALLWAITING_STOPPED",p->line_id);
+	brcm_send_ubus_event("CALLWAITING_STOPPED", p->line_id);
 	return 0;
 }
 
@@ -4204,8 +4229,9 @@ static int brcm_create_conference(struct brcm_pvt *p)
 static int brcm_stop_conference(struct brcm_subchannel *p)
 {
 	struct ast_bridge *confBridge;
-        struct brcm_pvt *pvt;
-        pvt = p->parent;
+	struct brcm_pvt *pvt;
+
+	pvt = p->parent;
 	if (p->connection_init && p->owner) {
 		ast_debug(1, "Ending conference for pvt line_id=%i connection_id=%d\n",
 			p->parent->line_id, p->connection_id);
@@ -4224,16 +4250,18 @@ static int brcm_stop_conference(struct brcm_subchannel *p)
 	return 0;
 }
 
-static int brcm_close_connection(struct brcm_subchannel *sub) {
+static int brcm_close_connection(struct brcm_subchannel *sub)
+{
+	struct brcm_pvt *p = sub->parent;
 
 	if (sub->connection_init) {
-		if(!brcm_in_onhold(sub->parent) && !brcm_in_call(sub->parent) &&
-			!brcm_in_callwaiting(sub->parent) && !brcm_in_transferring(sub->parent) ) { // Does line have another call?
-			ast_debug(1, "Closing real endpoint connection %d\n", sub->parent->line_id);
-			endpt_connection(sub->parent->line_id, sub->connection_id, "destroy");
+		if (!brcm_in_onhold(p) && !brcm_in_call(p) && !brcm_in_dialing(p) && !brcm_in_ringback(p) &&
+			!brcm_in_callwaiting(p) && !brcm_in_transferring(p)) { // Does the line have another call?
+			ast_debug(1, "Closing real endpoint connection %d\n", p->line_id);
+			endpt_connection(p->line_id, sub->connection_id, "destroy");
 		}
 		sub->connection_init = 0;
-		ast_debug(1, "Virtual Asterisk connection %d/%d destroyed\n", sub->parent->line_id, sub->connection_id);
+		ast_debug(1, "Virtual Asterisk connection %d/%d destroyed\n", p->line_id, sub->connection_id);
 	}
 
 	return 0;