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");