diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Codec/src/CSIPMessageParser.cpp --- /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 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; + }