Commit ade37b4e authored by urbant's avatar urbant
Browse files

Request line support

Method enumeration
parent f1e2f45f
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -5,10 +5,6 @@
namespace t3devlib {
namespace gen {

// enumerated types
typedef t3devlib::Boolean Method;


typedef t3devlib::Charstring CallidString;
typedef t3devlib::Charstring ContentCoding;
typedef t3devlib::Charstring	DeltaSec;	// an external operation can handle this field
@@ -46,6 +42,21 @@ public:
	void Decode (Buffer& buffer) throw (DecodeError);
};

// enumerated types
class Method : public t3devlib::Enum
{
private:
	static const char* msSipMethods[];
	static const char* msMethodValues[];
public:
	Method() : Enum (msSipMethods) {}

	const char* GetModuleName() const { return "LibSip_SIPTypesAndValues"; }
	const char* GetTypeName() const   { return "Method"; }

	void Encode (Buffer& buffer) throw (EncodeError);
	void Decode (Buffer& buffer) throw (DecodeError);
};

}} //namespaces

+118 −8
Original line number Diff line number Diff line
@@ -69,6 +69,13 @@ void remove_whitespace (Buffer & buffer) {
	}
}

void read_sp (Buffer & buffer, Variable* v) {
	static Regex reg_ws ("[ \t]+");
	reg_ws.AssertMatch (buffer, v);
	int nPos = buffer.GetPosition() + reg_ws.GetMatchedLength();
	buffer.SetPosition (nPos);
}

//whitespace


@@ -79,6 +86,10 @@ void remove_whitespace (Buffer & buffer) {
#define SIPCHARS_UNRESERVED	SIPCHARS_ALFANUM SIPCHARS_MARK
#define SIPCHARS_USER_UNRESERVED "&=+$,;?/"
#define SIPCHARS_ESCAPED	"(%[0-9A-F]{2})"
#define SIPCHARS_TOKEN "^[" SIPCHARS_ALFANUM ".!%*_+`'~\\-]+"

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

// host name
#define SIPCHARS_TOPLABEL	"[" SIPCHARS_ALFA "]([" SIPCHARS_ALFANUM "\\-]*[" SIPCHARS_ALFANUM "])?"
@@ -131,7 +142,7 @@ void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)

	case id_hostPort:
		if (IsPresent (id_userInfo)) {
			Unsigned(8).Decode(buffer);
			buffer.SetPosition(buffer.GetPosition() + 8);
		}
		if (reg_hostport.Match (buffer)) {
			SetHypFieldIsPresent (id,  1);
@@ -173,7 +184,7 @@ void UserInfo::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
		break;
	case id_password:
		if(buffer.GetBitsLeft()) {
			Unsigned(8).Decode(buffer);
			buffer.SetPosition(buffer.GetPosition() + 8);
			SetHypFieldIsPresent (id, 1);
			reg_password.AssertMatch (buffer, this);
		} else {
@@ -198,9 +209,8 @@ void HostPort::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
		break;
	case id_portField:
		if(buffer.GetBitsLeft()) {
			Unsigned(8).Decode(buffer);
			buffer.SetPosition(buffer.GetPosition() + 8);
			SetHypFieldIsPresent (id, 1);
			Get_portField().SetFormat(Integer::AsciiDecimal);
		} else {
			SetHypFieldIsPresent (id, 0);
		}
@@ -214,7 +224,7 @@ void SemicolonParam_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeE
	if (!buffer.GetBitsLeft())
		return;
	if (reg_separator.Match(buffer))
		Unsigned(8).Decode(buffer);
		buffer.SetPosition(buffer.GetPosition() + 8);
	else
		SetHypSize(-2);
}
@@ -228,10 +238,10 @@ void AmpersandParam_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeE
		return;
	if (GetSize() == 0){
		reg_start.AssertMatch(buffer, this);
		Unsigned(8).Decode(buffer);
		buffer.SetPosition(buffer.GetPosition() + 8);
	}
	else if (reg_separator.Match(buffer))
		Unsigned(8).Decode(buffer);
		buffer.SetPosition(buffer.GetPosition() + 8);
	else
		SetHypSize(-2);
}
@@ -281,7 +291,7 @@ void GenericParam::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
		if (bMandatoryParam)
			reg_equals.AssertMatch(buffer, this);
		if(bMandatoryParam || (buffer.GetBitsLeft() && reg_equals.Match(buffer))) {
			Unsigned(8).Decode(buffer);
			buffer.SetPosition(buffer.GetPosition() + 8);
			preg_value->AssertMatch (buffer, this);
			SetHypFieldIsPresent (id, 1);
			SetHypFieldLength (id, preg_value->GetMatchedLength());
@@ -292,6 +302,106 @@ 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_request_uri ("[^ \t\n\r]+", REG_ICASE);
	static Regex reg_sip_version (SIPCHARS_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:
			read_sp (buffer, this);
			reg_request_uri.AssertMatch (buffer, this);
			SetHypFieldLength (id, reg_request_uri.GetMatchedLength());
			break;
		case id_sipVersion:
			read_sp (buffer, this);
			reg_sip_version.AssertMatch (buffer, this);
			SetHypFieldLength (id, reg_sip_version.GetMatchedLength());
			break;
	}
}

const char* Method::msSipMethods[] = { 
	"ACK_E",
	"BYE_E",
	"CANCEL_E",
	"INVITE_E",
	"OPTIONS_E",
	"REGISTER_E",
	"PRACK_E",
	"SUBSCRIBE_E", 
	"NOTIFY_E",
	"PUBLISH_E",
	"REFER_E",
	"UPDATE_E",
	"MESSAGE_E",
	"INFO_E"
	, "" };

const char* Method::msMethodValues[] = { 
	"ACK",
	"BYE",
	"CANCEL",
	"INVITE",
	"OPTIONS",
	"REGISTER",
	"PRACK",
	"SUBSCRIBE", 
	"NOTIFY",
	"PUBLISH",
	"REFER",
	"UPDATE",
	"MESSAGE",
	"INFO"
	, "" };

void Method::Encode (Buffer& buffer) throw (EncodeError)
{
	Charstring c;
	const char ** ppMethod = msSipMethods;
	const std::string & val = GetValueString();

	int i = 0;
	while (*(ppMethod[i]) && stricmp(ppMethod[i], val.c_str()) != 0)
		i++;

	if (*(ppMethod[i]) == 0) {
		std::string message ("unsupported enum value '");
		message += val;
		throw EncodeError (this, message);
	}

	c.SetValue(msMethodValues[i]);
	c.Encode(buffer);
}

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

	reg_method.AssertMatch (buffer, this);

	const char ** ppValue = msMethodValues;
	const std::string & val = reg_method.GetMatchedString();

	int i = 0;
	while (*(ppValue[i]) && stricmp(ppValue[i], val.c_str()) != 0)
		i++;

	if (*(ppValue[i]) == 0) {
		std::string message ("unsupported enum value '");
		message += val;
		throw DecodeError (this, message);
	}

	SetValueString (msSipMethods[i]);
	buffer.SetPosition(buffer.GetPosition() + reg_method.GetMatchedLength());
}

class SipHeaderMap {
public: