/* Receive MRCP message through TCP/MRCPv2 connection */ static apt_bool_t mrcp_client_poller_signal_process(void *obj, const apr_pollfd_t *descriptor) { mrcp_connection_agent_t *agent = obj; mrcp_connection_t *connection = descriptor->client_data; apr_status_t status; apr_size_t offset; apr_size_t length; apt_text_stream_t *stream; mrcp_message_t *message; apt_message_status_e msg_status; if(!connection || !connection->sock) { return FALSE; } stream = &connection->rx_stream; /* calculate offset remaining from the previous receive / if any */ offset = stream->pos - stream->text.buf; /* calculate available length */ length = connection->rx_buffer_size - offset; status = apr_socket_recv(connection->sock,stream->pos,&length); if(status == APR_EOF || length == 0) { apt_pollset_t *pollset = apt_poller_task_pollset_get(agent->task); apt_log(APT_LOG_MARK,APT_PRIO_INFO,"TCP/MRCPv2 Peer Disconnected %s",connection->id); if(pollset) { apt_pollset_remove(pollset,&connection->sock_pfd); } apr_socket_close(connection->sock); connection->sock = NULL; mrcp_client_agent_disconnect_raise(agent,connection); return TRUE; } /* calculate actual length of the stream */ stream->text.length = offset + length; stream->pos[length] = '\0'; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive MRCPv2 Stream %s [%"APR_SIZE_T_FMT" bytes]\n%.*s", connection->id, length, connection->verbose == TRUE ? length : 0, stream->pos); /* reset pos */ apt_text_stream_reset(stream); do { msg_status = mrcp_parser_run(connection->parser,stream,&message); if(mrcp_client_message_handler(connection,message,msg_status) == FALSE) { return FALSE; } } while(apt_text_is_eos(stream) == FALSE); /* scroll remaining stream */ apt_text_stream_scroll(stream); return TRUE; }
static apt_bool_t mrcp_unirtsp_on_announce_response(mrcp_unirtsp_agent_t *agent, mrcp_unirtsp_session_t *session, rtsp_message_t *message, const char *resource_name) { mrcp_message_t *mrcp_message = NULL; if(!session || !resource_name) { return FALSE; } if(rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && message->header.content_type == RTSP_CONTENT_TYPE_MRCP && rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && message->header.content_length > 0) { apt_text_stream_t text_stream; mrcp_parser_t *parser; apt_str_t resource_name_str; text_stream.text = message->body; apt_text_stream_reset(&text_stream); apt_string_set(&resource_name_str,resource_name); parser = mrcp_parser_create(agent->sig_agent->resource_factory,session->mrcp_session->pool); mrcp_parser_resource_set(parser,&resource_name_str); if(mrcp_parser_run(parser,&text_stream,&mrcp_message) == APT_MESSAGE_STATUS_COMPLETE) { mrcp_message->channel_id.session_id = message->header.session_id; } else { /* error case */ apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse MRCPv1 Message"); } } else { /* error case */ apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Determine MRCPv1 Message Content"); } if(!mrcp_message) { if(!session->mrcp_message) { return FALSE; } mrcp_message = mrcp_response_create(session->mrcp_message,session->mrcp_session->pool); mrcp_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED; } if(session->mrcp_message && mrcp_message->start_line.request_id == session->mrcp_message->start_line.request_id) { session->mrcp_message = NULL; } mrcp_session_control_response(session->mrcp_session,mrcp_message); return TRUE; }
/** Walk through MRCP stream and invoke message handler for each parsed message */ MRCP_DECLARE(apt_bool_t) mrcp_stream_walk(mrcp_parser_t *parser, apt_text_stream_t *stream, mrcp_message_handler_f handler, void *obj) { mrcp_stream_result_e result; if(parser->skip_lf == TRUE) { /* skip <LF> occurred as a result of message segmentation between <CR> and <LF> */ apt_text_char_skip(stream,APT_TOKEN_LF); parser->skip_lf = FALSE; } do { result = mrcp_parser_run(parser,stream); if(result == MRCP_STREAM_MESSAGE_COMPLETE) { /* message is completely parsed */ apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Parsed MRCP Message [%lu]", stream->pos - stream->text.buf); /* invoke message handler */ handler(obj,parser->message,result); } else if(result == MRCP_STREAM_MESSAGE_TRUNCATED) { /* message is partially parsed, to be continued */ apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Truncated MRCP Message [%lu]", stream->pos - stream->text.buf); /* prepare stream for further processing */ if(apt_text_stream_scroll(stream) == TRUE) { apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Scroll MRCP Stream", stream->text.buf); } return TRUE; } else if(result == MRCP_STREAM_MESSAGE_INVALID){ /* error case */ apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse MRCP Message"); /* invoke message handler */ handler(obj,parser->message,result); /* reset stream pos */ stream->pos = stream->text.buf; return FALSE; } } while(apt_text_is_eos(stream) == FALSE); /* reset stream pos */ stream->pos = stream->text.buf; return TRUE; }
static apt_bool_t mrcp_unirtsp_session_announce(mrcp_unirtsp_agent_t *agent, mrcp_unirtsp_session_t *session, rtsp_message_t *message) { const char *resource_name = mrcp_name_get_by_rtsp_name( agent->config->resource_map, message->start_line.common.request_line.resource_name); apt_bool_t status = TRUE; if(session && resource_name && rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && message->header.content_type == RTSP_CONTENT_TYPE_MRCP && rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && message->header.content_length > 0) { apt_text_stream_t text_stream; mrcp_parser_t *parser; apt_str_t resource_name_str; text_stream.text = message->body; text_stream.pos = text_stream.text.buf; apt_string_set(&resource_name_str,resource_name); parser = mrcp_parser_create(agent->sig_agent->resource_factory,session->mrcp_session->pool); mrcp_parser_resource_name_set(parser,&resource_name_str); if(mrcp_parser_run(parser,&text_stream) == MRCP_STREAM_MESSAGE_COMPLETE) { mrcp_message_t *mrcp_message = mrcp_parser_message_get(parser); mrcp_message->channel_id.session_id = message->header.session_id; status = mrcp_session_control_request(session->mrcp_session,mrcp_message); } else { /* error response */ apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse MRCPv1 Message"); status = FALSE; } } else { /* error response */ status = FALSE; } return status; }