tsip_parser_message.jrl 4.38 KB
Newer Older
nextime's avatar
nextime committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
/*
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
* License: BSD
* This file is part of Open Source sipML5 solution <http://www.sipml5.org>
*/
function prev_not_comma(o_ragel_state, i_p){
	return (o_ragel_state.i_pe <= i_p) || (o_ragel_state.o_data[i_p - 1] != ',');
}

%%{
	machine tsip_machine_parser_message;

	#// Tag the buffer (start point)
	action tag {
		o_ragel_state.i_tag_start = p;
	}

	#// SIP method
	action parse_method {
	    o_ragel_state.i_tag_end = p;
		if(o_msg.e_type == tsip_message_type_e.UNKNOWN){
			o_msg.e_type = tsip_message_type_e.REQUEST;
			if(!o_msg.line.request.s_method){
			    o_msg.line.request.s_method = tsk_ragel_parser_get_string(o_ragel_state.s_data, p, o_ragel_state.i_tag_start);
				o_msg.line.request.e_type = tsip_message.prototype.GetRequestType(o_msg.line.request.s_method);
			}
		}
		else{
			o_ragel_state.cs = tsip_machine_parser_message_error;
		}
	}

	#// Request URI parsing
	action parse_requesturi {
	    o_ragel_state.i_tag_end = p;
		if(!o_msg.line.request.o_uri){
		    var s_uri = tsk_ragel_parser_get_string(o_ragel_state.s_data, p, o_ragel_state.i_tag_start);
			o_msg.line.request.o_uri = tsip_uri.prototype.Parse(s_uri);
		}
	}

	#// Sip Version
	action parse_sipversion {
	    o_ragel_state.i_tag_end = p;
		o_msg.s_version = tsk_ragel_parser_get_string(o_ragel_state.s_data, p, o_ragel_state.i_tag_start);
	}

	#// Status Code
	action parse_status_code {
	    o_ragel_state.i_tag_end = p;	
		if(o_msg.e_type == tsip_message_type_e.UNKNOWN){
			o_msg.e_type = tsip_message_type_e.RESPONSE;
			var s_status_code = tsk_ragel_parser_get_string(o_ragel_state.s_data, p, o_ragel_state.i_tag_start);
			o_msg.line.response.i_status_code = parseInt(s_status_code);
		}
		else{
			o_ragel_state.i_cs = tsip_machine_parser_message_error;
		}
	}

	#// Reason Phrase
	action parse_reason_phrase{
	    o_ragel_state.i_tag_end = p;
		if(!o_msg.line.response.s_reason_phrase){
			o_msg.line.response.s_reason_phrase = tsk_ragel_parser_get_string(o_ragel_state.s_data, p, o_ragel_state.i_tag_start);
		}
	}

	#// Parse sip header
	action parse_header{
	    o_ragel_state.i_tag_end = p;
		tsip_header_parse(o_ragel_state, o_msg);
	}

	#// End-Of-Headers
	action eoh{
		o_ragel_state.i_cs = cs;
		o_ragel_state.i_p = p;
		o_ragel_state.i_pe = pe;
		o_ragel_state.i_eof = eof;

		tsip_message_parser_eoh(o_ragel_state, o_msg, b_extract_content);

		cs = o_ragel_state.i_cs;
		p = o_ragel_state.i_p;
		pe = o_ragel_state.i_pe;
		eof = o_ragel_state.i_eof;
	}

	# Includes
	include tsip_machine_utils "./tsip_machine_utils.jrl";
	include tsip_machine_message "./tsip_machine_message.jrl";
	
	# Entry point
	main := SIP_message;
}%%

%%write data;

function tsip_message_parser_init(o_ragel_state){
	var cs = 0;

	// Ragel machine initialization.
	%% write init;
	
	o_ragel_state.i_cs = cs;
}

function tsip_message_parser_execute(o_ragel_state, o_msg, b_extract_content){
    var cs = o_ragel_state.i_cs;
	var p = o_ragel_state.i_p;
	var pe = o_ragel_state.i_pe;
	var eof = o_ragel_state.i_eof;
	var data = o_ragel_state.o_data;

	%% write exec;

    o_ragel_state.i_cs = cs;
	o_ragel_state.i_p = p;
	o_ragel_state.i_pe = pe;
	o_ragel_state.i_eof = eof;
}

function tsip_message_parser_eoh(o_ragel_state, o_msg, b_extract_content){
    if(o_msg && b_extract_content){
        var i_clen = o_msg.get_content_length();
        if((o_ragel_state.i_p + i_clen) < o_ragel_state.i_pe && !o_msg.o_content){
            var i_start = o_ragel_state.i_p + 1;
            var i_end = (i_start + i_clen);
			o_msg.o_content = new Array((i_end - i_start));
            for(var i = i_start, j = 0; i < i_end; ++i, ++j){
                o_msg.o_content[j] = o_ragel_state.o_data[i];
            }
            o_ragel_state.i_p += i_clen;
        }
        else{
            o_ragel_state.i_p = (o_ragel_state.i_pe - 1);
        }
    }
}

tsip_message.prototype.Parse = function(o_ragel_state, b_extract_content){
    var o_msg = null;
    if(!o_ragel_state || !o_ragel_state.o_data){
        return null;
    }
    
    o_msg = new tsip_message(tsip_message_type_e.UNKNOWN);
    
    // ragel init
    tsip_message_parser_init(o_ragel_state);
    
    // state machine execution
    tsip_message_parser_execute(o_ragel_state, o_msg, b_extract_content);
    
    if( o_ragel_state.i_cs < %%{ write first_final; }%% ){
		tsk_utils_log_error("Failed to parse message: " + o_ragel_state.s_data);
		return null;
	}
    
    return o_msg;
}