diff --git a/src/channels/chan_voicemngr.c b/src/channels/chan_voicemngr.c index 8784aae612a8c15b1ef84749d06bdf5d86d1e12b..2c68f70d37ff60bd3165c4423048340f96f16c80 100644 --- a/src/channels/chan_voicemngr.c +++ b/src/channels/chan_voicemngr.c @@ -176,6 +176,8 @@ static int onholdhanguptimeout = DEFAULT_ONHOLD_HANGUP_TIMEOUT; #define DEFAULT_MAX_SESSION_PER_EXTENSION 2 static int max_sessions_per_extension = DEFAULT_MAX_SESSION_PER_EXTENSION; +static int default_ptime = DEFAULT_PTIME; + /* Boolean, controls whether the transferor puts the transfer target on-hold before sending * REFER to the transferee */ static int hold_target_before_refer = 1; @@ -662,6 +664,42 @@ static void endpt_connection(int line, int id, char *action) { endpt_connection_data(line, id, action, NULL); } +static void chan_voicemngr_modify_codec(struct chan_voicemngr_subchannel *sub) { + if (sub->owner && sub->updated_codec != 1 ) { + ast_debug(4, "sub->owner Channel %s, ast_channel_codec_get(): %s\n",ast_channel_name(sub->owner), ast_channel_codec_get(sub->owner)); + ast_channel_unlock(sub->owner); + struct ast_channel *bridged_chan = ast_channel_bridge_peer(sub->owner); + ast_channel_lock(sub->owner); + + if (bridged_chan) { + ast_channel_ptime_set(sub->owner,ast_channel_ptime_get(bridged_chan)); + ast_channel_codec_set(sub->owner,ast_channel_codec_get(bridged_chan)); + ast_log(LOG_NOTICE, "Sync local codec to :%s, and ptime tp %d \n", ast_channel_codec_get(sub->owner), ast_channel_ptime_get(sub->owner)); + ao2_ref(bridged_chan, -1); + } else { + ast_channel_unlock(sub->owner); + return; + } + + char tmp[8] = {0}; + tmp[0] = '\0'; + if (ast_channel_codec_get(sub->owner)) { + strcpy(tmp, ast_channel_codec_get(sub->owner)); + } + if (tmp[0] != '\0') { + /* for ptime + if (ast_channel_ptime_get(sub->owner) && ast_channel_ptime_get(sub->owner) != sub->period){ + sub->period = ast_channel_ptime_get(sub->owner); + } + */ + endpt_connection_data(sub->parent->line_id, sub->call_id, "set_codec", tmp); + ast_log(LOG_NOTICE, "set codec: %s",tmp); + sub->updated_codec = 1; + } + ast_channel_unlock(sub->owner); + } +} + static int chan_voicemngr_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen) { struct chan_voicemngr_subchannel *sub = ast_channel_tech_pvt(ast); @@ -700,68 +738,7 @@ static int chan_voicemngr_indicate(struct ast_channel *ast, int condition, const sub->codec = -1; if (sub->channel_state == RINGBACK) endpt_signal(sub->parent->line_id, "ringback", "off", NULL); - - struct ast_bridge *bridge; - struct ast_bridge_channel *bridge_channel; - - if (sub->owner && sub->updated_codec != 1 ) { - ast_channel_lock(sub->owner); - ast_log(LOG_NOTICE, "sub->owner Channel %s, ast_channel_codec_get(): %s\n",ast_channel_name(sub->owner), ast_channel_codec_get(sub->owner)); - bridge = ast_channel_internal_bridge(sub->owner); - - if (sub->call_direction == INCOMING_CALL){ - // if incoming, set all the same as writeformat to avoid transcoding. - ast_channel_codec_set(sub->owner, ast_format_get_name(ast_channel_writeformat(sub->owner))); - ast_channel_set_rawreadformat(sub->owner, ast_channel_writeformat(sub->owner)); - ast_channel_set_rawwriteformat(sub->owner, ast_channel_writeformat(sub->owner)); - ast_channel_set_readformat(sub->owner, ast_channel_writeformat(sub->owner)); - ast_channel_set_writeformat(sub->owner, ast_channel_writeformat(sub->owner)); - } else { - // outgoing call, need sync with pjsip read format - if(bridge){ - AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) { - ast_log(LOG_NOTICE, "bridge Channel %s, ast_channel_codec_get(): %s, read formats: %s, write formats: %s\n", - ast_channel_name(bridge_channel->chan), - ast_channel_codec_get(bridge_channel->chan), - ast_format_get_name(bridge_channel->read_format), - ast_format_get_name(bridge_channel->write_format)); - - if ( strcmp(ast_channel_name(bridge_channel->chan), ast_channel_name(sub->owner)) ){ - // if bridge_chan != sub-owner, ie bridge_chan is pjsip_chan, sub-owner is tel_chan - // set bridge_chan codec/nativeformat as bridge_chan read format to avoid transcoding - // and sync sub-owner with bridge_chan read format. - ast_channel_codec_set(sub->owner, ast_format_get_name(ast_channel_readformat(bridge_channel->chan))); - ast_channel_lock(bridge_channel->chan); - ast_channel_codec_set(bridge_channel->chan, ast_format_get_name(ast_channel_readformat(bridge_channel->chan))); - struct ast_format_cap *caps; - caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); - ast_format_cap_append(caps, map_rtpname_to_format(ast_channel_codec_get(bridge_channel->chan)), 0); - - ast_channel_nativeformats_set(bridge_channel->chan, caps); - ast_channel_unlock(bridge_channel->chan); - ast_channel_nativeformats_set(sub->owner, caps); - ast_channel_set_rawreadformat(sub->owner, ast_channel_readformat(bridge_channel->chan)); - ast_channel_set_rawwriteformat(sub->owner, ast_channel_readformat(bridge_channel->chan)); - ast_channel_set_readformat(sub->owner, ast_channel_readformat(bridge_channel->chan)); - ast_channel_set_writeformat(sub->owner, ast_channel_readformat(bridge_channel->chan)); - - ast_log(LOG_NOTICE, "Channel %s gets an indication, condition = %d, sub->channel_state: %s, sub->codec: %d,ast_channel_codec_get(ast): %s\n", ast_channel_name(ast), - condition, state2str(sub->channel_state), sub->codec, ast_channel_codec_get(ast)); - } - } - } - } - char tmp[8] = {0}; - if (ast_channel_codec_get(sub->owner)) { - strcpy(tmp, ast_channel_codec_get(sub->owner)); - } - if (tmp[0] != '\0') { - endpt_connection_data(sub->parent->line_id, sub->call_id, "set_codec", tmp); - ast_log(LOG_NOTICE, "set codec: %s",tmp); - sub->updated_codec = 1; - } - ast_channel_unlock(sub->owner); - } + chan_voicemngr_modify_codec(sub); pvt_unlock(sub->parent); break; case AST_CONTROL_RINGING: @@ -1661,6 +1638,7 @@ static int chan_voicemngr_write(struct ast_channel *ast, struct ast_frame *frame /* set rtp payload type sent to voicemngr */ sub->codec = map_ast_codec_id_to_rtp(frame->subclass.format); + chan_voicemngr_modify_codec(sub); //in case of no bridge peer when doing the modify_codec during incoming call //ast_mutex_unlock(&sub->parent->lock); pvt_unlock(sub->parent); @@ -1813,8 +1791,11 @@ static struct ast_channel *chan_voicemngr_new(struct chan_voicemngr_subchannel * assignedids, requestor, 0, "TELCHAN/%d/%d", subchan->parent->line_id, subchan->connection_id); if (chan) { ast_channel_tech_set(chan, cur_tech); - - ast_format_cap_append_from_cap(caps, default_cap, AST_MEDIA_TYPE_UNKNOWN); + if (format) { + ast_format_cap_append_from_cap(caps, format, AST_MEDIA_TYPE_UNKNOWN); + } else { + ast_format_cap_append_from_cap(caps, default_cap, AST_MEDIA_TYPE_UNKNOWN); + } ast_channel_nativeformats_set(chan, caps); ao2_ref(caps, -1); fmt = ast_format_cap_get_format(ast_channel_nativeformats(chan), 0); @@ -3525,7 +3506,7 @@ static struct chan_voicemngr_pvt *chan_voicemngr_allocate_pvt(void) sub->r4_hangup_timer_id = -1; sub->onhold_hangup_timer_id = -1; sub->sip_client_id = -1; - sub->period = 20; // 20 ms + sub->period = default_ptime; // 20 ms sub->conference_initiator = 0; tmp->sub[i] = sub; sub->jitter_count = 0; @@ -4153,7 +4134,7 @@ static channel_settings channel_settings_create(void) .ringsignal = 1, .timeoutmsec = 4000, .autodial_timeoutmsec = 60000, - .period = 20, + .period = default_ptime, .hangup_xfer = 0, .dialtone_timeoutmsec = 20000, .offhook_nu_timeoutmsec = 60000, @@ -4321,10 +4302,17 @@ static int load_common_settings(struct ast_config **cfg) while (tok) { char *codec = ast_strdupa(tok); codec = ast_strip(codec); - ast_format_cap_append(default_cap, map_rtpname_to_format(codec), 0); + ast_format_cap_append(default_cap, map_rtpname_to_format(codec), default_ptime); tok = strtok_r(NULL, ",", &addr); } } + } else if (!strcasecmp(v->name, "ptime")) { + default_ptime = atoi(v->value); + if (!default_ptime || default_ptime < 10) { + default_ptime = DEFAULT_ONHOLD_HANGUP_TIMEOUT; + ast_log(LOG_WARNING, "Incorrect default_ptime '%s', defaulting to '%d'\n", + v->value, default_ptime); + } } v = v->next; diff --git a/src/channels/chan_voicemngr.h b/src/channels/chan_voicemngr.h index 763ab22e237e1c9b4920f5e86387f7bfff14867a..eb4aecbe7798c3206049a9ef129408fee215538a 100644 --- a/src/channels/chan_voicemngr.h +++ b/src/channels/chan_voicemngr.h @@ -20,6 +20,8 @@ #define RTP_PT_G729 18 #define RTP_PT_DTMF 101 +#define DEFAULT_PTIME 20 //ms + #define NOT_INITIALIZED -1 #define MAX_NUM_LINEID 30 #define PACKET_BUFFER_SIZE 1024