/** Parse MRCP speech-length value */ static apt_bool_t mrcp_speech_length_value_parse(mrcp_speech_length_value_t *speech_length, const apt_str_t *value, apr_pool_t *pool) { if(!value->length) { return FALSE; } switch(*value->buf) { case '+': speech_length->type = SPEECH_LENGTH_TYPE_NUMERIC_POSITIVE; break; case '-': speech_length->type = SPEECH_LENGTH_TYPE_NUMERIC_NEGATIVE; break; default : speech_length->type = SPEECH_LENGTH_TYPE_TEXT; } if(speech_length->type == SPEECH_LENGTH_TYPE_TEXT) { apt_string_copy(&speech_length->value.tag,value,pool); } else { mrcp_numeric_speech_length_t *numeric = &speech_length->value.numeric; apt_str_t str; apt_text_stream_t stream; stream.text = *value; apt_text_stream_reset(&stream); stream.pos++; if(apt_text_field_read(&stream,APT_TOKEN_SP,TRUE,&str) == FALSE) { return FALSE; } numeric->length = apt_size_value_parse(&str); if(apt_text_field_read(&stream,APT_TOKEN_SP,TRUE,&str) == FALSE) { return FALSE; } numeric->unit = apt_string_table_value_parse(speech_unit_string_table,SPEECH_UNIT_COUNT,&str); } return TRUE; }
/** Parse MRCP response-line */ static apt_bool_t mrcp_response_line_parse(mrcp_start_line_t *start_line, apt_text_stream_t *stream) { apt_str_t field; start_line->length = 0; if(start_line->version == MRCP_VERSION_2) { if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse message-length in response-line"); return FALSE; } start_line->length = apt_size_value_parse(&field); } if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse request-id in response-line"); return FALSE; } start_line->request_id = mrcp_request_id_parse(&field); if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse status-code in response-line"); return FALSE; } start_line->status_code = mrcp_status_code_parse(&field); if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse request-state in response-line"); return FALSE; } start_line->request_state = mrcp_request_state_parse(&field); return TRUE; }
/** Parse RTSP transport port range */ static apt_bool_t rtsp_port_range_parse(rtsp_port_range_t *port_range, apt_text_stream_t *stream) { apt_str_t value; /* read min value */ if(apt_text_field_read(stream,'-',TRUE,&value) == FALSE) { return FALSE; } port_range->min = (apr_port_t)apt_size_value_parse(&value); /* read optional max value */ if(apt_text_field_read(stream,';',TRUE,&value) == TRUE) { port_range->max = (apr_port_t)apt_size_value_parse(&value); } return TRUE; }
/** Parse name=value pair */ static apt_bool_t apt_pair_parse(apt_pair_t *pair, const apt_str_t *field, apr_pool_t *pool) { apt_text_stream_t stream; apt_str_t item; stream.text = *field; apt_text_stream_reset(&stream); /* read name */ if(apt_text_field_read(&stream,'=',TRUE,&item) == FALSE) { return FALSE; } apt_string_copy(&pair->name,&item,pool); /* read value */ apt_text_field_read(&stream,';',TRUE,&item); apt_string_copy(&pair->value,&item,pool); return TRUE; }
/** Parse text value of RTSP transport attrib (source/destination, e.t.c) */ static apt_bool_t rtsp_transport_attrib_value_parse(apt_str_t *value, apt_text_stream_t *stream, apr_pool_t *pool) { apt_str_t field; /* read value */ if(apt_text_field_read(stream,';',TRUE,&field) == FALSE) { return FALSE; } apt_string_copy(value,&field,pool); return TRUE; }
/** Parse RTSP transport protocol (RTP/AVP[/UDP]) */ static apt_bool_t rtsp_transport_protocol_parse(rtsp_transport_t *transport, const apt_str_t *value) { apt_str_t field; apt_text_stream_t stream; stream.text = *value; stream.pos = stream.text.buf; /* set the defaults */ transport->protocol = RTSP_TRANSPORT_RTP; transport->profile = RTSP_PROFILE_AVP; transport->lower_protocol = RTSP_LOWER_TRANSPORT_UDP; /* read transport protocol (RTP) */ if(apt_text_field_read(&stream,'/',TRUE,&field) == FALSE) { return FALSE; } transport->protocol = apt_string_table_id_find(rtsp_transport_string_table,RTSP_TRANSPORT_COUNT,&field); if(transport->protocol >= RTSP_TRANSPORT_COUNT) { return FALSE; } /* read transport profile (AVP) */ if(apt_text_field_read(&stream,'/',TRUE,&field) == FALSE) { return FALSE; } transport->profile = apt_string_table_id_find(rtsp_profile_string_table,RTSP_PROFILE_COUNT,&field); if(transport->profile >= RTSP_PROFILE_COUNT) { return FALSE; } /* read optional lower transport protocol (UDP) */ if(apt_text_field_read(&stream,'/',TRUE,&field) == TRUE) { transport->lower_protocol = apt_string_table_id_find(rtsp_lower_transport_string_table,RTSP_LOWER_TRANSPORT_COUNT,&field); if(transport->lower_protocol >= RTSP_LOWER_TRANSPORT_COUNT) { return FALSE; } } return TRUE; }
/** Parse MRCP request-line */ static apt_bool_t mrcp_request_line_parse(mrcp_start_line_t *start_line, apt_text_stream_t *stream) { apt_str_t field; if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse request-id in request-line"); return FALSE; } start_line->request_id = mrcp_request_id_parse(&field); if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse mrcp-version in request-line"); return FALSE; } start_line->request_state = mrcp_request_state_parse(&field); if(start_line->request_state == MRCP_REQUEST_STATE_UNKNOWN) { /* request-line */ start_line->message_type = MRCP_MESSAGE_TYPE_REQUEST; } else { /* event line */ start_line->message_type = MRCP_MESSAGE_TYPE_EVENT; if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse mrcp-version in request-line"); return FALSE; } } start_line->version = mrcp_version_parse(&field); if(start_line->version == MRCP_VERSION_UNKNOWN) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown mrcp-version"); return FALSE; } return TRUE; }
/** Parse RTSP transport */ static apt_bool_t rtsp_transport_parse(rtsp_transport_t *transport, const apt_str_t *line, apr_pool_t *pool) { apt_str_t field; apt_text_stream_t stream; stream.text = *line; stream.pos = stream.text.buf; /* read transport protocol (RTP/AVP[/UDP]) */ if(apt_text_field_read(&stream,';',TRUE,&field) == FALSE) { return FALSE; } /* parse transport protocol (RTP/AVP[/UDP]) */ if(rtsp_transport_protocol_parse(transport,&field) == FALSE) { return FALSE; } /* read transport attributes */ while(apt_text_field_read(&stream,';',TRUE,&field) == TRUE) { rtsp_transport_attrib_parse(transport,&field,pool); } return TRUE; }
/** Parse mrcp request-id list */ static apt_bool_t mrcp_request_id_list_parse(mrcp_request_id_list_t *request_id_list, const apt_str_t *value) { apt_str_t field; apt_text_stream_t stream; stream.text = *value; stream.pos = stream.text.buf; request_id_list->count = 0; while(request_id_list->count < MAX_ACTIVE_REQUEST_ID_COUNT) { if(apt_text_field_read(&stream,',',TRUE,&field) == FALSE) { break; } request_id_list->ids[request_id_list->count] = mrcp_request_id_parse(&field); request_id_list->count++; } return TRUE; }
/** Parse array of name-value pairs */ APT_DECLARE(apt_bool_t) apt_pair_array_parse(apt_pair_arr_t *arr, const apt_str_t *value, apr_pool_t *pool) { apt_str_t field; apt_pair_t *pair; apt_text_stream_t stream; if(!arr || !value) { return FALSE; } stream.text = *value; apt_text_stream_reset(&stream); /* read name-value pairs */ while(apt_text_field_read(&stream,';',TRUE,&field) == TRUE) { pair = apr_array_push(arr); apt_pair_parse(pair,&field,pool); } return TRUE; }
/** Parse MRCP v2 start-line */ static apt_bool_t mrcp_v2_start_line_parse(mrcp_start_line_t *start_line, apt_text_stream_t *stream, apr_pool_t *pool) { apt_str_t field; if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse message-length in v2 start-line"); return FALSE; } start_line->length = apt_size_value_parse(&field); if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse request-id in v2 start-line"); return FALSE; } start_line->request_id = mrcp_request_id_parse(&field); if(start_line->request_id == 0 && *field.buf != '0') { /* parsing MRCP v2 request or event */ start_line->message_type = MRCP_MESSAGE_TYPE_REQUEST; apt_string_copy(&start_line->method_name,&field,pool); if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse request-id in v2 start-line"); return FALSE; } start_line->request_id = mrcp_request_id_parse(&field); if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == TRUE) { /* parsing MRCP v2 event */ start_line->request_state = mrcp_request_state_parse(&field); start_line->message_type = MRCP_MESSAGE_TYPE_EVENT; } } else { /* parsing MRCP v2 response */ start_line->message_type = MRCP_MESSAGE_TYPE_RESPONSE; if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse status-code in v2 start-line"); return FALSE; } start_line->status_code = mrcp_status_code_parse(&field); if(apt_text_field_read(stream,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse request-state in v2 start-line"); return FALSE; } start_line->request_state = mrcp_request_state_parse(&field); } return TRUE; }
/** Parse RTSP transport */ static apt_bool_t rtsp_transport_attrib_parse(rtsp_transport_t *transport, const apt_str_t *field, apr_pool_t *pool) { rtsp_transport_attrib_e attrib; apt_str_t name; apt_text_stream_t stream; stream.text = *field; stream.pos = stream.text.buf; /* read attrib name */ if(apt_text_field_read(&stream,'=',TRUE,&name) == FALSE) { return FALSE; } attrib = apt_string_table_id_find(rtsp_transport_attrib_string_table,RTSP_TRANSPORT_ATTRIB_COUNT,&name); switch(attrib) { case RTSP_TRANSPORT_ATTRIB_CLIENT_PORT: rtsp_port_range_parse(&transport->client_port_range,&stream); break; case RTSP_TRANSPORT_ATTRIB_SERVER_PORT: rtsp_port_range_parse(&transport->client_port_range,&stream); break; case RTSP_TRANSPORT_ATTRIB_SOURCE: rtsp_transport_attrib_value_parse(&transport->source,&stream,pool); break; case RTSP_TRANSPORT_ATTRIB_DESTINATION: rtsp_transport_attrib_value_parse(&transport->destination,&stream,pool); break; case RTSP_TRANSPORT_ATTRIB_UNICAST: transport->delivery = RTSP_DELIVERY_UNICAST; break; case RTSP_TRANSPORT_ATTRIB_MULTICAST: transport->delivery = RTSP_DELIVERY_MULTICAST; break; case RTSP_TRANSPORT_ATTRIB_MODE: rtsp_transport_attrib_value_parse(&transport->mode,&stream,pool); break; default: break; } return TRUE; }
/** Parse MRCP start-line */ MRCP_DECLARE(apt_bool_t) mrcp_start_line_parse(mrcp_start_line_t *start_line, apt_text_stream_t *text_stream, apr_pool_t *pool) { apt_text_stream_t line; apt_str_t field; apt_bool_t status = TRUE; start_line->message_type = MRCP_MESSAGE_TYPE_UNKNOWN; if(apt_text_line_read(text_stream,&line.text) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse MRCP start-line"); return FALSE; } apt_text_stream_reset(&line); if(apt_text_field_read(&line,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot read the first field in start-line"); return FALSE; } if(field.buf == strstr(field.buf,MRCP_NAME)) { start_line->version = mrcp_version_parse(&field); if(start_line->version == MRCP_VERSION_1) { /* parsing MRCP v1 response */ start_line->message_type = MRCP_MESSAGE_TYPE_RESPONSE; status = mrcp_response_line_parse(start_line,&line); } else if(start_line->version == MRCP_VERSION_2) { /* parsing MRCP v2 start-line (request/response/event) */ status = mrcp_v2_start_line_parse(start_line,&line,pool); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown MRCP version"); return FALSE; } } else { /* parsing MRCP v1 request or event */ apt_string_copy(&start_line->method_name,&field,pool); status = mrcp_request_line_parse(start_line,&line); } return status; }