Commit 2c193dae authored by urbant's avatar urbant
Browse files

Status line

parent cf2a5258
Loading
Loading
Loading
Loading
+84 −59
Original line number Diff line number Diff line
#include "gen_classes.h"

#include <regex.h>


namespace t3devlib { namespace gen {

class Regex {
@@ -84,20 +82,23 @@ void read_sp (Buffer & buffer, Variable* v) {
#define SIPCHARS_ALFANUM	"0-9" SIPCHARS_ALFA
#define SIPCHARS_HEXA	"0-9A-F"
#define SIPCHARS_UNRESERVED	SIPCHARS_ALFANUM SIPCHARS_MARK
#define SIPCHARS_RESERVED	";/?:@&=+$,"
#define SIPCHARS_USER_UNRESERVED "&=+$,;?/"
#define SIPCHARS_ESCAPED	"(%[0-9A-F]{2})"
#define SIPCHARS_TOKEN "^[" SIPCHARS_ALFANUM ".!%*_+`'~\\-]+"
#define SIPCHARS_UTF8_NONASCII	"\xC0-\xFD"
#define SIPCHARS_UTF8_CONTENT	"\x80-\xBF"
#define SIPREG_ESCAPED	"(%[0-9A-F]{2})"
#define SIPREG_TOKEN "^[" SIPCHARS_ALFANUM ".!%*_+`'~\\-]+"

//FIXME: WSP is not clearly defined (all whitespaces) 
#define SIPCHARS_WSP		" 	"

// sip version
#define SIPCHARS_SIP_VERSION "SIP/[0-9].[0-9]"
#define SIPREG_SIP_VERSION "SIP/[0-9].[0-9]"

// host name
#define SIPCHARS_TOPLABEL	"[" SIPCHARS_ALFA "]([" SIPCHARS_ALFANUM "\\-]*[" SIPCHARS_ALFANUM "])?"
#define SIPCHARS_DOMAINLABEL	"[" SIPCHARS_ALFANUM "]([" SIPCHARS_ALFANUM "\\-]*[" SIPCHARS_ALFANUM "])?"
#define SIPCHARS_HOSTNAME	"(" SIPCHARS_DOMAINLABEL "\\.)*" SIPCHARS_TOPLABEL "\\.?"
#define SIPREG_TOPLABEL	"[" SIPCHARS_ALFA "]([" SIPCHARS_ALFANUM "\\-]*[" SIPCHARS_ALFANUM "])?"
#define SIPREG_DOMAINLABEL	"[" SIPCHARS_ALFANUM "]([" SIPCHARS_ALFANUM "\\-]*[" SIPCHARS_ALFANUM "])?"
#define SIPREG_HOSTNAME	"(" SIPREG_DOMAINLABEL "\\.)*" SIPREG_TOPLABEL "\\.?"


#define SIPREG_LWS		"([" SIPCHARS_WSP "]*\r\n)?[" SIPCHARS_WSP "]+"
@@ -105,33 +106,33 @@ void read_sp (Buffer & buffer, Variable* v) {
#define SIPREG_HCOLON		"[ 	]*:" SIPREG_SWS

// IPv4
#define SIPCHARS_IP4	"([0-9]{1,3}\\.){3}[0-9]{1,3}"
#define SIPREG_IP4	"([0-9]{1,3}\\.){3}[0-9]{1,3}"

// IPv6
#define SIPCHARS_HEX4		"[" SIPCHARS_HEXA "]{1,4}"
#define SIPCHARS_HEXSEQ		SIPCHARS_HEX4 "([:]" SIPCHARS_HEX4 ")*"
#define SIPCHARS_HEXPART	"(((" SIPCHARS_HEXSEQ ")?[:]{2}(" SIPCHARS_HEXSEQ ")?)|(" SIPCHARS_HEXSEQ  "))"
#define SIPCHARS_IP6		"[[]" SIPCHARS_HEXPART "([:]" SIPCHARS_IP4 ")?[]]"
#define SIPREG_HEX4		"[" SIPCHARS_HEXA "]{1,4}"
#define SIPREG_HEXSEQ		SIPREG_HEX4 "([:]" SIPREG_HEX4 ")*"
#define SIPREG_HEXPART	"(((" SIPREG_HEXSEQ ")?[:]{2}(" SIPREG_HEXSEQ ")?)|(" SIPREG_HEXSEQ  "))"
#define SIPREG_IP6		"[[]" SIPREG_HEXPART "([:]" SIPREG_IP4 ")?[]]"

// host
#define SIPCHARS_HOST		"((" SIPCHARS_HOSTNAME ")|(" SIPCHARS_IP4 ")|(" SIPCHARS_IP6 "))"
#define SIPREG_HOST		"((" SIPREG_HOSTNAME ")|(" SIPREG_IP4 ")|(" SIPREG_IP6 "))"

#define SIPCHARS_PPARAM_UNRESERVED "][/:&+$"
#define SIPCHARS_PPARAM		"([" SIPCHARS_PPARAM_UNRESERVED SIPCHARS_UNRESERVED "]|" SIPCHARS_ESCAPED "])"
#define SIPCHARS_PPARAM_ALLOWED	"[" SIPCHARS_PPARAM_UNRESERVED SIPCHARS_UNRESERVED ";=%]+"
#define SIPREG_PPARAM		"([" SIPCHARS_PPARAM_UNRESERVED SIPCHARS_UNRESERVED "]|" SIPREG_ESCAPED ")"
#define SIPREG_PPARAM_ALLOWED	"[" SIPCHARS_PPARAM_UNRESERVED SIPCHARS_UNRESERVED ";=%]+"

#define SIPCHARS_HPARAM_UNRESERVED "][/?:+$"
#define SIPCHARS_HPARAM		"([" SIPCHARS_HPARAM_UNRESERVED SIPCHARS_UNRESERVED "]|" SIPCHARS_ESCAPED "])"
#define SIPCHARS_HPARAM_ALLOWED	"[" SIPCHARS_HPARAM_UNRESERVED SIPCHARS_UNRESERVED ";=%]+"
#define SIPREG_HPARAM		"([" SIPCHARS_HPARAM_UNRESERVED SIPCHARS_UNRESERVED "]|" SIPREG_ESCAPED ")"
#define SIPREG_HPARAM_ALLOWED	"[" SIPCHARS_HPARAM_UNRESERVED SIPCHARS_UNRESERVED ";=%]+"

void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{

	static Regex reg_scheme ("^sip[s]?:", REG_ICASE);
	static Regex reg_userinfo ("^([:" SIPCHARS_UNRESERVED SIPCHARS_USER_UNRESERVED "]|" SIPCHARS_ESCAPED "])+@", REG_ICASE);
	static Regex reg_userinfo ("^([:" SIPCHARS_UNRESERVED SIPCHARS_USER_UNRESERVED "]|" SIPREG_ESCAPED "])+@", REG_ICASE);
	static Regex reg_hostport ("^[][" SIPCHARS_ALFANUM ":.\\-]+", REG_ICASE);
	static Regex reg_urlParams ("^;" SIPCHARS_PPARAM_ALLOWED, REG_ICASE);
	static Regex reg_headers ("^[?]" SIPCHARS_PPARAM_ALLOWED, REG_ICASE);
	static Regex reg_urlParams ("^;" SIPREG_PPARAM_ALLOWED, REG_ICASE);
	static Regex reg_headers ("^[?]" SIPREG_PPARAM_ALLOWED, REG_ICASE);

	switch (id) {
	case id_scheme:
@@ -182,8 +183,8 @@ void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)

void UserInfo::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_username ("^([" SIPCHARS_UNRESERVED SIPCHARS_USER_UNRESERVED "]|" SIPCHARS_ESCAPED ")+:", REG_ICASE);
	static Regex reg_password ("^([&=+$," SIPCHARS_UNRESERVED "]|" SIPCHARS_ESCAPED ")*", REG_ICASE);
	static Regex reg_username ("^([" SIPCHARS_UNRESERVED SIPCHARS_USER_UNRESERVED "]|" SIPREG_ESCAPED ")+:", REG_ICASE);
	static Regex reg_password ("^([&=+$," SIPCHARS_UNRESERVED "]|" SIPREG_ESCAPED ")*", REG_ICASE);
	switch (id) {
	case id_userOrTelephoneSubscriber:
		if (reg_username.Match (buffer)) {
@@ -204,8 +205,8 @@ void UserInfo::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)

void HostPort::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_host1 (SIPCHARS_HOST, REG_ICASE);
	static Regex reg_host2 (SIPCHARS_HOST ":", REG_ICASE);
	static Regex reg_host1 ("^" SIPREG_HOST, REG_ICASE);
	static Regex reg_host2 ("^" SIPREG_HOST ":", REG_ICASE);
	switch (id) {
	case id_host:
		SetHypFieldIsPresent(id, 1);
@@ -259,11 +260,11 @@ void GenericParam::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_equals ("^=", REG_ICASE);

	static Regex reg_pparname ("^" SIPCHARS_PPARAM "+", REG_ICASE);
	static Regex reg_pparvalue ("^" SIPCHARS_PPARAM "*", REG_ICASE);
	static Regex reg_pparname ("^" SIPREG_PPARAM "+", REG_ICASE);
	static Regex reg_pparvalue ("^" SIPREG_PPARAM "*", REG_ICASE);

	static Regex reg_hparname ("^" SIPCHARS_HPARAM "+", REG_ICASE);
	static Regex reg_hparvalue ("^" SIPCHARS_HPARAM "*", REG_ICASE);
	static Regex reg_hparname ("^" SIPREG_HPARAM "+", REG_ICASE);
	static Regex reg_hparvalue ("^" SIPREG_HPARAM "*", REG_ICASE);

	Regex * preg_name;
	Regex * preg_value;
@@ -313,13 +314,12 @@ void GenericParam::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)

void RequestLine::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_method (SIPCHARS_TOKEN, REG_ICASE);
	static Regex reg_method (SIPREG_TOKEN, REG_ICASE);
	static Regex reg_request_uri ("[^ \t\n\r]+", REG_ICASE);
	static Regex reg_sip_version (SIPCHARS_SIP_VERSION, REG_ICASE);
	static Regex reg_sip_version (SIPREG_SIP_VERSION, REG_ICASE);
	switch (id) {
		case id_method:
			reg_method.AssertMatch (buffer, this);
			cout << "detected length: " << reg_method.GetMatchedLength() << "\n";
			SetHypFieldLength (id, reg_method.GetMatchedLength());
			break;
		case id_requestUri:
@@ -391,7 +391,7 @@ void Method::Encode (Buffer& buffer) throw (EncodeError)

void Method::Decode (Buffer& buffer) throw (DecodeError)
{
	static Regex reg_method (SIPCHARS_TOKEN, REG_ICASE);
	static Regex reg_method (SIPREG_TOKEN, REG_ICASE);

	reg_method.AssertMatch (buffer, this);

@@ -412,6 +412,31 @@ void Method::Decode (Buffer& buffer) throw (DecodeError)
	buffer.SetPosition(buffer.GetPosition() + reg_method.GetMatchedLength());
}

void StatusLine::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_sip_version (SIPREG_SIP_VERSION, REG_ICASE);
	static Regex reg_status_code ("^[0-9]{3}", REG_ICASE);
	static Regex reg_phrase ("([" SIPCHARS_RESERVED SIPCHARS_UNRESERVED SIPCHARS_UTF8_NONASCII SIPCHARS_UTF8_CONTENT " \t]|" SIPREG_ESCAPED ")*", REG_ICASE);

	switch (id) {
		case id_sipVersion:
			reg_sip_version.AssertMatch (buffer, this);
			SetHypFieldLength (id, reg_sip_version.GetMatchedLength());
			break;
		case id_statusCode:
			read_sp (buffer, this);
			reg_status_code.AssertMatch (buffer, this);
			SetHypFieldLength (id, reg_status_code.GetMatchedLength());
			Get_statusCode().SetFormat(Integer::AsciiDecimal);
			break;
		case id_reasonPhrase:
			read_sp (buffer, this);
			reg_phrase.AssertMatch (buffer, this);
			SetHypFieldLength (id, reg_phrase.GetMatchedLength());			
			break;
	}
}

class SipHeaderMap {
public:
	struct Entry {