--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Codec/src/CSIPMessageParser.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,262 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name : CSIPMessageParser.cpp
+// Part of : SIP Codec
+// Version : SIP/4.0
+//
+
+
+
+#include "sipmessageparser.h"
+#include "CSIPPreParser.h"
+#include "TSIPHeaderNameValueIter.h"
+#include "CSIPHeaderNameValue.h"
+#include "SIPHeaderLookup.h"
+#include "sipcodecerr.h"
+#include "sipmessage.h"
+#include "siprequest.h"
+#include "sipresponse.h"
+#include "sipheaderbase.h"
+#include "sipuri.h"
+#include "uricontainer.h"
+#include "_sipcodecdefs.h"
+
+_LIT8(KSIPWithSlash, "SIP/");
+
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPMessageParser* CSIPMessageParser::NewL ()
+ {
+ CSIPMessageParser* self= CSIPMessageParser::NewLC ();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPMessageParser* CSIPMessageParser::NewLC ()
+ {
+ CSIPMessageParser* self=new(ELeave) CSIPMessageParser;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::CSIPMessageParser
+// -----------------------------------------------------------------------------
+//
+CSIPMessageParser::CSIPMessageParser()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageParser::ConstructL ()
+ {
+ SIPHeaderLookup::OpenL ();
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::~CSIPMessageParser
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPMessageParser::~CSIPMessageParser()
+ {
+ SIPHeaderLookup::Close ();
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::FromText
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CSIPMessageParser::FromText (HBufC8* aInputSIPMessage,
+ CSIPMessage** aSIPMessage)
+ {
+ TInt parseErrorInHeaders=KErrNone;
+ CSIPMessage* sipMessage = 0;
+ TRAPD (err, sipMessage = FromTextL (aInputSIPMessage,parseErrorInHeaders));
+ *aSIPMessage = sipMessage;
+ if (err == KErrNone)
+ {
+ err = parseErrorInHeaders;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::FromTextL
+// -----------------------------------------------------------------------------
+//
+CSIPMessage* CSIPMessageParser::FromTextL (HBufC8* aInputSIPMessage,
+ TInt& aParseErrorInHeaders)
+ {
+ __ASSERT_ALWAYS (aInputSIPMessage != 0, User::Leave(KErrArgument));
+
+ aParseErrorInHeaders = KErrNone;
+ CSIPPreParser* preParser = CSIPPreParser::NewL(aInputSIPMessage);
+ CleanupStack::PushL(preParser);
+ CSIPMessage* sipMessage = CreateSIPMessageLC (preParser->FirstLineL());
+
+ TSIPHeaderNameValueIter iter (*preParser);
+ while (!iter.End())
+ {
+ CSIPHeaderNameValue* header = iter.NextL ();
+ RPointerArray<CSIPHeaderBase> headerArray;
+ TRAPD (err, headerArray =
+ SIPHeaderLookup::CreateHeaderL(header->Name(),header->Value()));
+ delete header;
+ if (err == KErrNoMemory)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ if (err == KErrNone)
+ {
+ CSIPHeaderBase::PushLC(&headerArray);
+ for (TInt i=0; i < headerArray.Count(); i++)
+ {
+ sipMessage->AddHeaderL (headerArray[i]);
+ headerArray[i] = 0;
+ }
+ CleanupStack::PopAndDestroy(1); // headerArray
+ }
+ else // ignore header with syntax error
+ {
+ // Set the first error
+ if (aParseErrorInHeaders == KErrNone)
+ {
+ aParseErrorInHeaders = err;
+ }
+ }
+ }
+
+ HBufC8* content = preParser->ContentL();
+ sipMessage->SetContent (content);
+ CleanupStack::Pop(sipMessage);
+ CleanupStack::PopAndDestroy(preParser);
+ return sipMessage;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::CreateSIPMessageLC
+// -----------------------------------------------------------------------------
+//
+CSIPMessage* CSIPMessageParser::CreateSIPMessageLC (const TDesC8& aFirstLine)
+ {
+ CSIPMessage* sipMessage = NULL;
+
+ if (aFirstLine.FindF(KSIPWithSlash) == 0)
+ {
+ sipMessage = CreateSIPResponseLC(aFirstLine);
+ }
+ else
+ {
+ sipMessage = CreateSIPRequestLC(aFirstLine);
+ }
+
+ return sipMessage;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::CreateSIPRequestLC
+// -----------------------------------------------------------------------------
+//
+CSIPRequest* CSIPMessageParser::CreateSIPRequestLC (const TDesC8& aRequestLine)
+ {
+ __ASSERT_ALWAYS (aRequestLine.Length()>0,
+ User::Leave(KErrSipCodecRequestLine));
+
+ //Method SP Request-URI SP SIP-Version
+ CSIPRequest* sipRequest = CSIPRequest::NewLC();
+ TLex8 lex(aRequestLine);
+
+ //Method
+ TPtrC8 method = lex.NextToken();
+ sipRequest->SetMethodL(method);
+
+ //Request-URI
+ CURIContainer* uri = CURIContainer::DecodeL(lex.NextToken());
+ CleanupStack::PushL(uri);
+ sipRequest->SetRequestURIL (uri);
+ CleanupStack::Pop(uri);
+
+ //SIP-Version
+ sipRequest->SetSIPVersionL(lex.NextToken());
+
+ return sipRequest;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::CreateSIPResponseLC
+// -----------------------------------------------------------------------------
+//
+CSIPResponse* CSIPMessageParser::CreateSIPResponseLC (const TDesC8& aStatusLine)
+ {
+ __ASSERT_ALWAYS (aStatusLine.Length()>0,
+ User::Leave(KErrSipCodecResponseLine));
+
+ //SIP-Version SP Status-Code SP Reason-Phrase
+ CSIPResponse* sipResponse = CSIPResponse::NewL();
+ CleanupStack::PushL (sipResponse);
+ TLex8 lex(aStatusLine);
+
+ sipResponse->SetSIPVersionL (lex.NextToken());
+ sipResponse->SetResponseCodeL (ParseResponseCodeL(lex.NextToken()));
+ if (lex.Get() != ' ')
+ {
+ User::Leave(KErrSipCodecResponseLine);
+ }
+ sipResponse->SetReasonPhraseL (lex.Remainder());
+
+ return sipResponse;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageParser::ParseResponseCodeL
+// -----------------------------------------------------------------------------
+//
+TUint CSIPMessageParser::ParseResponseCodeL (const TDesC8& aResponseCode)
+ {
+ __ASSERT_ALWAYS (aResponseCode.Length() > 0,
+ User::Leave (KErrSipCodecResponseCode));
+
+ TLex8 lex(aResponseCode);
+ TUint chrCount=0;
+ lex.Mark();
+ TChar chr = lex.Get();
+ while (chr)
+ {
+ chrCount++;
+ chr = lex.Get();
+ }
+ const TInt KCharactersInResponseCode = 3;
+ if (chrCount != KCharactersInResponseCode)
+ {
+ User::Leave (KErrSipCodecResponseCode);
+ }
+ lex.UnGetToMark();
+ TUint value=0;
+ if (lex.Val(value) != KErrNone)
+ {
+ User::Leave (KErrSipCodecResponseCode);
+ }
+ return value;
+ }