realtimenetprots/sipfw/SIP/Codec/src/CSIPMessageParser.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : CSIPMessageParser.cpp
       
    15 // Part of       : SIP Codec
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "sipmessageparser.h"
       
    22 #include "CSIPPreParser.h"
       
    23 #include "TSIPHeaderNameValueIter.h"
       
    24 #include "CSIPHeaderNameValue.h"
       
    25 #include "SIPHeaderLookup.h"
       
    26 #include "sipcodecerr.h"
       
    27 #include "sipmessage.h"
       
    28 #include "siprequest.h"
       
    29 #include "sipresponse.h"
       
    30 #include "sipheaderbase.h"
       
    31 #include "sipuri.h"
       
    32 #include "uricontainer.h"
       
    33 #include "_sipcodecdefs.h"
       
    34 
       
    35 _LIT8(KSIPWithSlash, "SIP/");
       
    36 
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CSIPMessageParser::NewL
       
    40 // -----------------------------------------------------------------------------
       
    41 //
       
    42 EXPORT_C CSIPMessageParser* CSIPMessageParser::NewL ()
       
    43 	{
       
    44 	CSIPMessageParser* self= CSIPMessageParser::NewLC ();
       
    45 	CleanupStack::Pop(self);
       
    46 	return self;
       
    47 	}
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // CSIPMessageParser::NewLC
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 EXPORT_C CSIPMessageParser* CSIPMessageParser::NewLC ()
       
    54 	{
       
    55 	CSIPMessageParser* self=new(ELeave) CSIPMessageParser;
       
    56 	CleanupStack::PushL(self);
       
    57 	self->ConstructL();
       
    58 	return self;
       
    59 	}
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // CSIPMessageParser::CSIPMessageParser
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 CSIPMessageParser::CSIPMessageParser()
       
    66 	{
       
    67 	}
       
    68 
       
    69 // -----------------------------------------------------------------------------
       
    70 // CSIPMessageParser::ConstructL
       
    71 // -----------------------------------------------------------------------------
       
    72 //
       
    73 void CSIPMessageParser::ConstructL ()
       
    74 	{
       
    75 	SIPHeaderLookup::OpenL ();
       
    76 	}
       
    77 
       
    78 // -----------------------------------------------------------------------------
       
    79 // CSIPMessageParser::~CSIPMessageParser
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 EXPORT_C CSIPMessageParser::~CSIPMessageParser()
       
    83 	{
       
    84 	SIPHeaderLookup::Close ();
       
    85 	}
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CSIPMessageParser::FromText
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 EXPORT_C TInt CSIPMessageParser::FromText (HBufC8* aInputSIPMessage,
       
    92 										   CSIPMessage** aSIPMessage)
       
    93 	{
       
    94 	TInt parseErrorInHeaders=KErrNone;
       
    95 	CSIPMessage* sipMessage = 0;
       
    96 	TRAPD (err, sipMessage = FromTextL (aInputSIPMessage,parseErrorInHeaders));
       
    97 	*aSIPMessage = sipMessage;
       
    98 	if (err == KErrNone)
       
    99 	    {
       
   100 	    err = parseErrorInHeaders;    
       
   101 	    }
       
   102 	return err;
       
   103 	}
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // CSIPMessageParser::FromTextL
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 CSIPMessage* CSIPMessageParser::FromTextL (HBufC8* aInputSIPMessage,
       
   110 										   TInt& aParseErrorInHeaders)
       
   111 	{
       
   112 	__ASSERT_ALWAYS (aInputSIPMessage != 0, User::Leave(KErrArgument));
       
   113 
       
   114 	aParseErrorInHeaders = KErrNone;
       
   115 	CSIPPreParser* preParser = CSIPPreParser::NewL(aInputSIPMessage);
       
   116 	CleanupStack::PushL(preParser);
       
   117 	CSIPMessage* sipMessage = CreateSIPMessageLC (preParser->FirstLineL());
       
   118 
       
   119 	TSIPHeaderNameValueIter iter (*preParser);
       
   120 	while (!iter.End())
       
   121 		{
       
   122 		CSIPHeaderNameValue* header = iter.NextL ();
       
   123 		RPointerArray<CSIPHeaderBase> headerArray;
       
   124 		TRAPD (err, headerArray = 
       
   125 			SIPHeaderLookup::CreateHeaderL(header->Name(),header->Value()));
       
   126 		delete header;
       
   127 		if (err == KErrNoMemory) 
       
   128 			{
       
   129 			User::Leave(KErrNoMemory);
       
   130 			}
       
   131 		if (err == KErrNone)
       
   132 			{
       
   133 			CSIPHeaderBase::PushLC(&headerArray);
       
   134 			for (TInt i=0; i < headerArray.Count(); i++)
       
   135 				{
       
   136 				sipMessage->AddHeaderL (headerArray[i]);
       
   137 				headerArray[i] = 0;
       
   138 				}
       
   139 			CleanupStack::PopAndDestroy(1); // headerArray
       
   140 			}
       
   141 		else // ignore header with syntax error
       
   142 			{
       
   143 			// Set the first error 
       
   144 			if (aParseErrorInHeaders == KErrNone) 
       
   145 				{
       
   146 				aParseErrorInHeaders = err;
       
   147 				}
       
   148 			}
       
   149 		}
       
   150 
       
   151 	HBufC8* content = preParser->ContentL();
       
   152 	sipMessage->SetContent (content);
       
   153 	CleanupStack::Pop(sipMessage);
       
   154 	CleanupStack::PopAndDestroy(preParser);
       
   155 	return sipMessage;
       
   156 	}
       
   157 
       
   158 // -----------------------------------------------------------------------------
       
   159 // CSIPMessageParser::CreateSIPMessageLC
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 CSIPMessage* CSIPMessageParser::CreateSIPMessageLC (const TDesC8& aFirstLine)
       
   163 	{
       
   164 	CSIPMessage* sipMessage = NULL;
       
   165 
       
   166 	if (aFirstLine.FindF(KSIPWithSlash) == 0)
       
   167 		{
       
   168 		sipMessage = CreateSIPResponseLC(aFirstLine);
       
   169 		}
       
   170 	else
       
   171 		{
       
   172 		sipMessage = CreateSIPRequestLC(aFirstLine);
       
   173 		}
       
   174 
       
   175 	return sipMessage;
       
   176 	}
       
   177 
       
   178 // -----------------------------------------------------------------------------
       
   179 // CSIPMessageParser::CreateSIPRequestLC
       
   180 // -----------------------------------------------------------------------------
       
   181 //
       
   182 CSIPRequest* CSIPMessageParser::CreateSIPRequestLC (const TDesC8& aRequestLine)
       
   183 	{
       
   184 	__ASSERT_ALWAYS (aRequestLine.Length()>0, 
       
   185 	                 User::Leave(KErrSipCodecRequestLine));
       
   186 
       
   187 	//Method SP Request-URI SP SIP-Version
       
   188 	CSIPRequest* sipRequest = CSIPRequest::NewLC();
       
   189 	TLex8 lex(aRequestLine);
       
   190 
       
   191 	//Method
       
   192 	TPtrC8 method = lex.NextToken();
       
   193 	sipRequest->SetMethodL(method);
       
   194 
       
   195     //Request-URI
       
   196     CURIContainer* uri = CURIContainer::DecodeL(lex.NextToken());
       
   197     CleanupStack::PushL(uri);
       
   198     sipRequest->SetRequestURIL (uri);
       
   199     CleanupStack::Pop(uri);
       
   200 
       
   201 	//SIP-Version
       
   202 	sipRequest->SetSIPVersionL(lex.NextToken());
       
   203 
       
   204 	return sipRequest;
       
   205 	}
       
   206 
       
   207 // -----------------------------------------------------------------------------
       
   208 // CSIPMessageParser::CreateSIPResponseLC
       
   209 // -----------------------------------------------------------------------------
       
   210 //
       
   211 CSIPResponse* CSIPMessageParser::CreateSIPResponseLC (const TDesC8& aStatusLine)
       
   212 	{
       
   213 	__ASSERT_ALWAYS (aStatusLine.Length()>0, 
       
   214 	                 User::Leave(KErrSipCodecResponseLine));
       
   215 
       
   216 	//SIP-Version SP Status-Code SP Reason-Phrase
       
   217 	CSIPResponse* sipResponse = CSIPResponse::NewL();
       
   218 	CleanupStack::PushL (sipResponse);
       
   219 	TLex8 lex(aStatusLine);
       
   220 
       
   221 	sipResponse->SetSIPVersionL (lex.NextToken());
       
   222 	sipResponse->SetResponseCodeL (ParseResponseCodeL(lex.NextToken()));
       
   223 	if (lex.Get() != ' ')
       
   224 		{
       
   225 		User::Leave(KErrSipCodecResponseLine);
       
   226 		}
       
   227 	sipResponse->SetReasonPhraseL (lex.Remainder());
       
   228 
       
   229 	return sipResponse;
       
   230 	}
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // CSIPMessageParser::ParseResponseCodeL
       
   234 // -----------------------------------------------------------------------------
       
   235 //
       
   236 TUint CSIPMessageParser::ParseResponseCodeL (const TDesC8& aResponseCode)
       
   237 	{
       
   238 	__ASSERT_ALWAYS (aResponseCode.Length() > 0,
       
   239 					 User::Leave (KErrSipCodecResponseCode));
       
   240 
       
   241 	TLex8 lex(aResponseCode);
       
   242 	TUint chrCount=0;
       
   243 	lex.Mark();
       
   244 	TChar chr = lex.Get();
       
   245 	while (chr)
       
   246 		{
       
   247 		chrCount++;
       
   248 		chr = lex.Get();
       
   249 		}
       
   250     const TInt KCharactersInResponseCode = 3;
       
   251 	if (chrCount != KCharactersInResponseCode) 
       
   252 		{
       
   253 		User::Leave (KErrSipCodecResponseCode);
       
   254 		}
       
   255 	lex.UnGetToMark();
       
   256 	TUint value=0;
       
   257 	if (lex.Val(value) != KErrNone) 
       
   258 		{
       
   259 		User::Leave (KErrSipCodecResponseCode);
       
   260 		}
       
   261 	return value;
       
   262 	}