예제 #1
0
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;
}
예제 #3
0
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;
}
예제 #4
0
파일: mrcp_sdp.c 프로젝트: salzh/freeswitch
/** 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);
}
예제 #6
0
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);
}
예제 #7
0
/** 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;
}
예제 #8
0
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;
}