diff --git a/channels/chan_brcm.c b/channels/chan_brcm.c
index 7f28f0660b2bfa7bf9e7a3acfa18d82c292bc699..7da003050b8e986b636e45e8fd5ce2ee89139231 100644
--- a/channels/chan_brcm.c
+++ b/channels/chan_brcm.c
@@ -702,11 +702,27 @@ static void chan_brcm_modify_codec(struct brcm_subchannel *sub) {
 		ast_channel_lock(sub->owner);
 
 		if (bridged_chan) {
-			// for the internal call, bridged_chan is allocated but codec and ptime is not set so need to check it here and set default
-			// ptime and get codec from sub-owner in this case
+			// bridged_chan is allocated but codec and ptime is not set so need to check it here and set default
 			ast_channel_ptime_set(sub->owner, ast_channel_ptime_get(bridged_chan) ? ast_channel_ptime_get(bridged_chan) : default_ptime);
-			ast_channel_codec_set(sub->owner, !ast_strlen_zero(ast_channel_codec_get(bridged_chan)) ?
-				ast_channel_codec_get(bridged_chan) : ast_format_get_name(ast_channel_writeformat(sub->owner)));
+			if (strncmp(ast_channel_name(bridged_chan), "TELCHAN", 5) == 0 ) {
+				// local chan, internal call, using alaw.
+				ast_log(LOG_NOTICE, "INTERNAL CALL, %s\n", ast_channel_name(bridged_chan));
+				ast_channel_codec_set(sub->owner, "alaw");
+				ast_channel_codec_set(bridged_chan, "alaw");
+				struct ast_format_cap *caps;
+				caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+				if (caps) {
+					ast_format_cap_append(caps, map_rtpname_to_format("alaw"), 0);
+					ast_channel_nativeformats_set(bridged_chan, caps);
+					ao2_ref(caps, -1);
+				} else {
+					ao2_cleanup(caps);
+				}
+			} else {
+			// get codec from bridged_chan's writeformat if not set
+				ast_channel_codec_set(sub->owner, !ast_strlen_zero(ast_channel_codec_get(bridged_chan)) ?
+					ast_channel_codec_get(bridged_chan) : ast_format_get_name(ast_channel_writeformat(bridged_chan)));
+			}
 			// we need to set caps here from bridged_chan to avoid asterisk transcoding which break audio in some cases
 			struct ast_format_cap *caps;
 			caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
@@ -829,6 +845,10 @@ static int brcm_indicate(struct ast_channel *ast, int condition, const void *dat
 				ast_log(LOG_ERROR, "can't get the peer channel, unattended call transfer will not be proceeded\n");
 			}
 
+		} else if(sub->channel_state == INCALL) {
+			/* for some specific scenarios, unhold was wrong indicate as unhold_for_transfer from pjsip
+			just redirect to unhold to make less effect to transfer */
+			ast_indicate(sub->owner, AST_CONTROL_UNHOLD);
 		}
 		break;
 	case AST_CONTROL_TRANSFER:
@@ -1601,7 +1621,7 @@ static int brcm_write(struct ast_channel *ast, struct ast_frame *frame)
 	struct brcm_subchannel *sub = ast_channel_tech_pvt(ast);
 	int packet_size;
 	audio_packet_t *ap;
-	unsigned int rtp_timestamp = frame->ts * (ast_rtp_get_rate(frame->subclass.format)/1000);
+	unsigned int rtp_timestamp = frame->ts ? frame->ts * (ast_rtp_get_rate(frame->subclass.format)/1000) : 0;
 
 	if (ast_channel_state(ast) != AST_STATE_UP && ast_channel_state(ast) != AST_STATE_RING) {
 		/* Silently ignore packets until channel is up */
@@ -2520,6 +2540,8 @@ static void handle_Rkey_uk(struct brcm_subchannel *sub, struct brcm_subchannel *
 				ast_queue_hold(owner, NULL);
 			}
 			ast_log(LOG_NOTICE, " R in Call waiting\n");
+			/* Stop call waiting tone on current call */
+			brcm_stop_callwaiting(p);
 			/* Cancel timers */
 			if (ast_sched_del(sched, sub_peer->cw_timer_id)) {
 				ast_log(LOG_WARNING, "Failed to remove scheduled call waiting timer\n");