/** Create RTP tx remote descriptor */ static mpf_rtp_stream_descriptor_t* mpf_rtp_tx_remote_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session) { mpf_codec_list_t *codec_list; mpf_codec_descriptor_t *codec_descriptor; mpf_rtp_media_descriptor_t *media_descriptor; mpf_rtp_stream_descriptor_t *stream_descriptor; media_descriptor = mpf_rtp_media_descriptor_alloc(session->pool); media_descriptor->state = MPF_MEDIA_ENABLED; media_descriptor->direction = STREAM_DIRECTION_RECEIVE; apt_string_set(&media_descriptor->ip,"127.0.0.1"); media_descriptor->port = 5000; codec_list = &media_descriptor->codec_list; mpf_codec_list_init(codec_list,1,session->pool); codec_descriptor = mpf_codec_list_add(codec_list); if(codec_descriptor) { codec_descriptor->payload_type = 0; apt_string_set(&codec_descriptor->name,"PCMU"); codec_descriptor->sampling_rate = 8000; codec_descriptor->channel_count = 1; } stream_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_stream_descriptor_t)); mpf_rtp_stream_descriptor_init(stream_descriptor); stream_descriptor->remote = media_descriptor; stream_descriptor->settings = agent->rtp_settings; return stream_descriptor; }
/** Create RTP tx local descriptor */ static mpf_rtp_stream_descriptor_t* mpf_rtp_tx_local_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session) { mpf_rtp_media_descriptor_t *media_descriptor; mpf_rtp_stream_descriptor_t *stream_descriptor; media_descriptor = mpf_rtp_media_descriptor_alloc(session->pool); media_descriptor->state = MPF_MEDIA_ENABLED; media_descriptor->direction = STREAM_DIRECTION_SEND; apt_string_set(&media_descriptor->ip,"127.0.0.1"); media_descriptor->port = 5002; stream_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_stream_descriptor_t)); mpf_rtp_stream_descriptor_init(stream_descriptor); stream_descriptor->local = media_descriptor; stream_descriptor->settings = agent->rtp_settings; return stream_descriptor; }
static apt_bool_t mpf_rtp_stream_local_media_create(mpf_rtp_stream_t *rtp_stream, mpf_rtp_media_descriptor_t *local_media, mpf_rtp_media_descriptor_t *remote_media, mpf_stream_capabilities_t *capabilities) { apt_bool_t status = TRUE; if(!local_media) { /* local media is not specified, create the default one */ local_media = mpf_rtp_media_descriptor_alloc(rtp_stream->pool); local_media->state = MPF_MEDIA_ENABLED; local_media->direction = STREAM_DIRECTION_DUPLEX; } if(remote_media) { local_media->id = remote_media->id; } if(local_media->ip.length == 0) { local_media->ip = rtp_stream->config->ip; local_media->ext_ip = rtp_stream->config->ext_ip; } if(local_media->port == 0) { if(mpf_rtp_socket_pair_create(rtp_stream,local_media,FALSE) == TRUE) { /* RTP port management */ mpf_rtp_config_t *rtp_config = rtp_stream->config; apr_port_t first_port_in_search = rtp_config->rtp_port_cur; apt_bool_t is_port_ok = FALSE; do { local_media->port = rtp_config->rtp_port_cur; rtp_config->rtp_port_cur += 2; if(rtp_config->rtp_port_cur == rtp_config->rtp_port_max) { rtp_config->rtp_port_cur = rtp_config->rtp_port_min; } if(mpf_rtp_socket_pair_bind(rtp_stream,local_media) == TRUE) { is_port_ok = TRUE; break; } } while(first_port_in_search != rtp_config->rtp_port_cur); if(is_port_ok == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find Free RTP Port %s:[%hu,%hu]", rtp_config->ip.buf, rtp_config->rtp_port_min, rtp_config->rtp_port_max); mpf_rtp_socket_pair_close(rtp_stream); status = FALSE; } } else { status = FALSE; } } else if(mpf_rtp_socket_pair_create(rtp_stream,local_media,TRUE) == FALSE) { status = FALSE; } if(status == FALSE) { local_media->state = MPF_MEDIA_DISABLED; } if(rtp_stream->settings->ptime) { local_media->ptime = rtp_stream->settings->ptime; } if(mpf_codec_list_is_empty(&local_media->codec_list) == TRUE) { if(mpf_codec_list_is_empty(&rtp_stream->settings->codec_list) == TRUE) { mpf_codec_manager_codec_list_get( rtp_stream->base->termination->codec_manager, &local_media->codec_list, rtp_stream->pool); } else { mpf_codec_list_copy(&local_media->codec_list, &rtp_stream->settings->codec_list, rtp_stream->pool); } } if(capabilities) { if(mpf_codec_list_match(&local_media->codec_list,&capabilities->codecs) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Match Codec List %s:%hu", local_media->ip.buf, local_media->port); local_media->state = MPF_MEDIA_DISABLED; status = FALSE; } } rtp_stream->local_media = local_media; return status; }
static apt_bool_t mrcp_client_channel_add(mrcp_client_session_t *session, mrcp_channel_t *channel) { mpf_rtp_termination_descriptor_t *rtp_descriptor = NULL; rtp_termination_slot_t *slot; apr_pool_t *pool = session->base.pool; mrcp_client_profile_t *profile = session->profile; if(mrcp_client_channel_find(session,channel,NULL) == TRUE) { /* update */ return mrcp_client_channel_modify(session,channel,TRUE); } if(!session->offer) { session->offer = mrcp_session_descriptor_create(pool); } mrcp_client_session_state_set(session,SESSION_STATE_GENERATING_OFFER); if(mrcp_session_version_get(session) == MRCP_VERSION_1) { session->offer->resource_name = channel->resource->name; session->offer->resource_state = TRUE; } else { mrcp_control_descriptor_t *control_media; if(!channel->control_channel) { channel->control_channel = mrcp_client_control_channel_create(session->base.connection_agent,channel,pool); mrcp_client_control_channel_log_obj_set(channel->control_channel,session->base.log_obj); } control_media = mrcp_control_offer_create(pool); control_media->id = mrcp_session_control_media_add(session->offer,control_media); mrcp_cmid_add(control_media->cmid_arr,session->offer->control_media_arr->nelts); control_media->resource_name = channel->resource->name; if(mrcp_client_control_channel_add(channel->control_channel,control_media) == TRUE) { channel->waiting_for_channel = TRUE; mrcp_client_session_subrequest_add(session); } } apt_obj_log(APT_LOG_MARK,APT_PRIO_NOTICE,session->base.log_obj,"Add Control Channel " APT_NAMESIDRES_FMT, MRCP_SESSION_NAMESID(session), channel->resource->name.buf); /* add control channel */ APR_ARRAY_PUSH(session->channels,mrcp_channel_t*) = channel; /* add rtp termination slot */ slot = apr_array_push(session->terminations); slot->waiting = FALSE; slot->termination = NULL; slot->descriptor = NULL; slot->channel = channel; slot->id = 0; if(channel->termination) { /* media termination mode */ mpf_termination_t *termination; mpf_audio_stream_t *audio_stream; if(!session->context) { /* create media context first */ session->context = mpf_engine_context_create( session->base.media_engine, session->base.name, session,5,pool); } apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Add Media Termination " APT_NAMESIDRES_FMT, MRCP_SESSION_NAMESID(session), mpf_termination_name_get(channel->termination)); if(mpf_engine_termination_message_add( session->base.media_engine, MPF_ADD_TERMINATION,session->context,channel->termination,NULL, &session->mpf_task_msg) == TRUE) { channel->waiting_for_termination = TRUE; mrcp_client_session_subrequest_add(session); } /* initialize rtp descriptor */ rtp_descriptor = mpf_rtp_termination_descriptor_alloc(pool); rtp_descriptor->audio.settings = profile->rtp_settings; audio_stream = mpf_termination_audio_stream_get(channel->termination); if(audio_stream) { mpf_rtp_media_descriptor_t *media = mpf_rtp_media_descriptor_alloc(pool); media->state = MPF_MEDIA_ENABLED; media->direction = mpf_stream_reverse_direction_get(audio_stream->direction); rtp_descriptor->audio.local = media; if(audio_stream->capabilities) { rtp_descriptor->audio.capabilities = mpf_stream_capabilities_clone(audio_stream->capabilities,pool); rtp_descriptor->audio.capabilities->direction = media->direction; } } /* create rtp termination */ termination = mpf_termination_create(session->base.rtp_factory,session,pool); slot->termination = termination; apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Add Media Termination " APT_NAMESIDRES_FMT, MRCP_SESSION_NAMESID(session), mpf_termination_name_get(termination)); /* send add termination request (add to media context) */ if(mpf_engine_termination_message_add( session->base.media_engine, MPF_ADD_TERMINATION,session->context,termination,rtp_descriptor, &session->mpf_task_msg) == TRUE) { slot->waiting = TRUE; mrcp_client_session_subrequest_add(session); } mpf_engine_message_send(session->base.media_engine,&session->mpf_task_msg); } else { /* bypass media mode */ if(channel->rtp_termination_slot) { rtp_descriptor = channel->rtp_termination_slot->descriptor; if(rtp_descriptor) { if(rtp_descriptor->audio.local) { session->offer->ip = rtp_descriptor->audio.local->ip; session->offer->ext_ip = rtp_descriptor->audio.local->ext_ip; rtp_descriptor->audio.local->id = mrcp_session_audio_media_add(session->offer,rtp_descriptor->audio.local); rtp_descriptor->audio.local->mid = session->offer->audio_media_arr->nelts; slot->id = session->offer->audio_media_arr->nelts - 1; } } } } slot->descriptor = rtp_descriptor; channel->rtp_termination_slot = slot; if(!session->subrequest_count) { /* send offer to server */ mrcp_client_session_offer_send(session); } return TRUE; }