/* * 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; }