static apt_bool_t mrcp_server_engine_channels_update(mrcp_server_session_t *session) { mrcp_channel_t *channel; mrcp_session_descriptor_t *descriptor = session->offer; if(!descriptor) { return FALSE; } mrcp_server_session_state_set(session,SESSION_STATE_INITIALIZING); if(mrcp_session_version_get(session) == MRCP_VERSION_1) { if(session->offer) { channel = mrcp_server_channel_find(session,&descriptor->resource_name); if(channel && channel->engine_channel) { /* open engine channel */ if(mrcp_engine_channel_virtual_open(channel->engine_channel) == TRUE) { mrcp_server_session_subrequest_add(session); } } } } else { int i; mrcp_control_descriptor_t *control_descriptor; for(i=0; i<session->channels->nelts; i++) { channel = APR_ARRAY_IDX(session->channels,i,mrcp_channel_t*); if(!channel || !channel->engine_channel) continue; control_descriptor = mrcp_session_control_media_get(descriptor,i); if(!control_descriptor) continue; if(control_descriptor->port) { /* open engine channel */ if(mrcp_engine_channel_virtual_open(channel->engine_channel) == TRUE) { mrcp_server_session_subrequest_add(session); } } else { /* close engine channel */ if(mrcp_engine_channel_virtual_close(channel->engine_channel) == TRUE) { mrcp_server_session_subrequest_add(session); } } } } if(!session->subrequest_count) { mrcp_server_session_answer_send(session); } return TRUE; }
static apt_bool_t mrcp_client_control_media_answer_process(mrcp_client_session_t *session, mrcp_session_descriptor_t *descriptor) { mrcp_channel_t *channel; mrcp_control_descriptor_t *control_descriptor; int i; int count = session->channels->nelts; if(count != descriptor->control_media_arr->nelts) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Number of control channels [%d] != Number of control media in answer [%d]", count,descriptor->control_media_arr->nelts); count = descriptor->control_media_arr->nelts; } if(!session->base.id.length) { /* initial answer received, store session id and add to session's table */ control_descriptor = mrcp_session_control_media_get(descriptor,0); if(control_descriptor) { session->base.id = control_descriptor->session_id; } } /* update existing control channels */ for(i=0; i<count; i++) { /* get existing channel */ channel = APR_ARRAY_IDX(session->channels,i,mrcp_channel_t*); if(!channel) continue; /* get control descriptor */ control_descriptor = mrcp_session_control_media_get(descriptor,i); /* modify channel */ apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Modify Control Channel "APT_NAMESID_FMT, MRCP_SESSION_NAMESID(session)); if(mrcp_client_control_channel_modify(channel->control_channel,control_descriptor) == TRUE) { channel->waiting_for_channel = TRUE; mrcp_client_session_subrequest_add(session); } } return TRUE; }
static apt_bool_t mrcp_client_control_media_answer_process(mrcp_client_session_t *session, mrcp_session_descriptor_t *descriptor) { mrcp_channel_t *channel; mrcp_control_descriptor_t *control_descriptor; int i; int count = session->channels->nelts; if(count != descriptor->control_media_arr->nelts) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Number of control channels [%d] != Number of control media in answer [%d]", count,descriptor->control_media_arr->nelts); count = descriptor->control_media_arr->nelts; } if(!session->base.id.length) { /* initial answer received, store session id and add to session's table */ control_descriptor = mrcp_session_control_media_get(descriptor,0); if(control_descriptor) { session->base.id = control_descriptor->session_id; mrcp_client_session_add(session->application->client,session); } } /* update existing control channels */ for(i=0; i<count; i++) { /* get existing channel */ channel = *((mrcp_channel_t**)session->channels->elts + i); if(!channel) continue; /* get control descriptor */ control_descriptor = mrcp_session_control_media_get(descriptor,i); /* modify channel */ apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify Control Channel"); if(mrcp_client_control_channel_modify(channel->control_channel,control_descriptor) == TRUE) { channel->waiting_for_channel = TRUE; session->answer_flag_count++; } } return TRUE; }
/** Generate SDP string by MRCP descriptor */ MRCP_DECLARE(apr_size_t) sdp_string_generate_by_mrcp_descriptor(char *buffer, apr_size_t size, const mrcp_session_descriptor_t *descriptor, apt_bool_t offer) { apr_size_t i; apr_size_t count; apr_size_t audio_index = 0; mpf_rtp_media_descriptor_t *audio_media; apr_size_t video_index = 0; mpf_rtp_media_descriptor_t *video_media; apr_size_t control_index = 0; mrcp_control_descriptor_t *control_media; apr_size_t offset = 0; const char *ip = descriptor->ext_ip.buf ? descriptor->ext_ip.buf : (descriptor->ip.buf ? descriptor->ip.buf : "0.0.0.0"); buffer[0] = '\0'; offset += snprintf(buffer+offset,size-offset, "v=0\r\n" "o=%s 0 0 IN IP4 %s\r\n" "s=-\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n", descriptor->origin.buf ? descriptor->origin.buf : "-", ip, ip); count = mrcp_session_media_count_get(descriptor); for(i=0; i<count; i++) { audio_media = mrcp_session_audio_media_get(descriptor,audio_index); if(audio_media && audio_media->id == i) { /* generate audio media */ audio_index++; offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,audio_media); continue; } video_media = mrcp_session_video_media_get(descriptor,video_index); if(video_media && video_media->id == i) { /* generate video media */ video_index++; offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,video_media); continue; } control_media = mrcp_session_control_media_get(descriptor,control_index); if(control_media && control_media->id == i) { /** generate mrcp control media */ control_index++; offset += sdp_control_media_generate(buffer+offset,size-offset,descriptor,control_media,offer); continue; } } return offset; }
static apt_bool_t mrcp_client_channel_modify(mrcp_client_session_t *session, mrcp_channel_t *channel, apt_bool_t enable) { int index; if(!session->offer) { return FALSE; } if(!channel->resource) { return FALSE; } apt_obj_log(APT_LOG_MARK,APT_PRIO_NOTICE,session->base.log_obj,"Modify Control Channel "APT_NAMESIDRES_FMT" [%d]", MRCP_SESSION_NAMESID(session), channel->resource->name.buf, enable); if(mrcp_client_channel_find(session,channel,&index) == TRUE) { mrcp_control_descriptor_t *control_media = mrcp_session_control_media_get(session->offer,(apr_size_t)index); if(control_media) { control_media->port = (enable == TRUE) ? TCP_DISCARD_PORT : 0; } if(channel->termination && channel->rtp_termination_slot) { mpf_audio_stream_t *audio_stream = mpf_termination_audio_stream_get( channel->termination); mpf_rtp_media_descriptor_t *audio_media = mrcp_session_audio_media_get( session->offer, channel->rtp_termination_slot->id); if(audio_media && audio_stream) { mpf_stream_direction_e direction = mpf_stream_reverse_direction_get(audio_stream->direction); if(enable == TRUE) { audio_media->direction |= direction; } else { audio_media->direction &= ~direction; } audio_media->state = (audio_media->direction != STREAM_DIRECTION_NONE) ? MPF_MEDIA_ENABLED : MPF_MEDIA_DISABLED; } } } session->offer->resource_name = channel->resource->name; session->offer->resource_state = enable; return mrcp_client_session_offer_send(session); }
static apt_bool_t mrcp_client_channel_modify(mrcp_client_session_t *session, mrcp_channel_t *channel, apt_bool_t enable) { int index; if(!session->offer) { return FALSE; } if(!channel->resource_name) { return FALSE; } apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Modify Control Channel <%s@%s> [%d]", mrcp_session_str(session), channel->resource_name->buf, enable); if(mrcp_client_channel_find(session,channel,&index) == TRUE) { mrcp_control_descriptor_t *control_media = mrcp_session_control_media_get(session->offer,(apr_size_t)index); if(control_media) { control_media->port = (enable == TRUE) ? 9 : 0; if(channel->termination && channel->termination->audio_stream) { int i = mrcp_client_audio_media_find_by_mid(session->offer,control_media->cmid); if(i >= 0) { mpf_stream_mode_e mode = mpf_stream_mode_negotiate(channel->termination->audio_stream->mode); mpf_rtp_media_descriptor_t *audio_media = mrcp_session_audio_media_get(session->offer,(apr_size_t)i); if(audio_media) { if(enable == TRUE) { audio_media->mode |= mode; } else { audio_media->mode &= ~mode; } audio_media->base.state = (audio_media->mode != STREAM_MODE_NONE) ? MPF_MEDIA_ENABLED : MPF_MEDIA_DISABLED; } } } } } session->offer->resource_name = *channel->resource_name; session->offer->resource_state = enable; return mrcp_client_session_offer_send(session); }
/** Handle the responses sent to resource discover requests */ static apt_bool_t discover_application_on_resource_discover(mrcp_application_t *application, mrcp_session_t *session, mrcp_session_descriptor_t *descriptor, mrcp_sig_status_code_e status) { if(descriptor && status == MRCP_SIG_STATUS_CODE_SUCCESS) { int i; int count = descriptor->control_media_arr->nelts; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"On Resource Discover [%d]", count); for(i = 0; i < count; i++) { mrcp_control_descriptor_t *control_media = mrcp_session_control_media_get(descriptor,i); if(control_media) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"[%d] - %s", i,control_media->resource_name.buf); } } } else { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Failed to Discover Resources"); } mrcp_application_session_terminate(session); return TRUE; }
static apt_bool_t mrcp_server_control_media_offer_process(mrcp_server_session_t *session, mrcp_session_descriptor_t *descriptor) { mrcp_channel_t *channel; mrcp_control_descriptor_t *control_descriptor; int i; int count = session->channels->nelts; if(count > descriptor->control_media_arr->nelts) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Number of Control Channels [%d] > Number of Control Media in Offer [%d]", count,descriptor->control_media_arr->nelts); count = descriptor->control_media_arr->nelts; } /* update existing control channels */ for(i=0; i<count; i++) { /* get existing termination */ channel = *((mrcp_channel_t**)session->channels->elts + i); if(!channel) continue; channel->waiting_for_channel = FALSE; /* get control descriptor */ control_descriptor = mrcp_session_control_media_get(descriptor,i); if(!control_descriptor) continue; apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify Control Channel [%d]",i); if(channel->control_channel) { /* send offer */ if(mrcp_server_control_channel_modify(channel->control_channel,control_descriptor) == TRUE) { channel->waiting_for_channel = TRUE; session->answer_flag_count++; } } if(channel->waiting_for_channel == FALSE) { mrcp_control_descriptor_t *answer = mrcp_control_answer_create(control_descriptor,channel->pool); answer->port = 0; answer->session_id = session->base.id; mrcp_session_control_media_set(session->answer,channel->id,answer); } } /* add new control channels */ for(; i<descriptor->control_media_arr->nelts; i++) { mrcp_channel_t **slot; /* get control descriptor */ control_descriptor = mrcp_session_control_media_get(descriptor,i); if(!control_descriptor) continue; /* create new MRCP channel instance */ channel = mrcp_server_channel_create(session,&control_descriptor->resource_name,i); if(!channel) continue; /* add to channel array */ control_descriptor->session_id = session->base.id; apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Control Channel [%d]",i); slot = apr_array_push(session->channels); *slot = channel; if(channel->control_channel) { /* send modify connection request */ if(mrcp_server_control_channel_add(channel->control_channel,control_descriptor) == TRUE) { channel->waiting_for_channel = TRUE; session->answer_flag_count++; } } if(channel->waiting_for_channel == FALSE) { mrcp_control_descriptor_t *answer = mrcp_control_answer_create(control_descriptor,channel->pool); answer->port = 0; answer->session_id = session->base.id; mrcp_session_control_media_set(session->answer,channel->id,answer); } if(channel->engine_channel) { /* open resource engine channel */ if(mrcp_engine_channel_open(channel->engine_channel) == TRUE) { mpf_termination_t *termination = channel->engine_channel->termination; session->answer_flag_count++; if(termination) { /* send add termination request (add to media context) */ if(mrcp_server_mpf_request_send(session,MPF_COMMAND_ADD,session->context,termination,NULL) == TRUE) { channel->waiting_for_termination = TRUE; session->answer_flag_count++; } } } } } return TRUE; }