diff -r 000000000000 -r 9cfd9a3ee49c networkprotocolmodules/common/suplrrlpasn1/src/suplasn1decoderimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkprotocolmodules/common/suplrrlpasn1/src/suplasn1decoderimpl.cpp Tue Feb 02 01:50:39 2010 +0200 @@ -0,0 +1,271 @@ +// Copyright (c) 2008-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: +// Internal implementation of the SUPL ASN1 Decoder +// +// + +/** + @file + @internalTechnology + +*/ + +#include "ULP.h" +#include "suplasn1decoderimpl.h" +#include "suplinit.h" +#include "suplresponse.h" +#include "suplpos.h" +#include "suplend.h" +#include "supldevloggermacros.h" + +/** +Static factory constructor +*/ +EXPORT_C CSuplAsn1DecoderImpl* CSuplAsn1DecoderImpl::NewL() + { + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::NewL() Begin\n"); + CSuplAsn1DecoderImpl* self = new (ELeave) CSuplAsn1DecoderImpl(); + CleanupStack::PushL(self); + self->ConstructL(); + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::NewL() End\n"); + CleanupStack::Pop(self); + return self; + } + +/** +Constructor +*/ +CSuplAsn1DecoderImpl::CSuplAsn1DecoderImpl() + { + } + +/** +Second stage constructor +*/ +void CSuplAsn1DecoderImpl::ConstructL() + { + } + +/** +Destructor +*/ +CSuplAsn1DecoderImpl::~CSuplAsn1DecoderImpl() + { + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::~CSuplAsn1DecoderImpl() Begin\n"); + delete iDecodeBuffer; + delete iData; + delete iControl; + // release the STDLIB resources associated with this thread + CloseSTDLIB(); + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::~CSuplAsn1DecoderImpl() End\n"); + } + +/** +DecodeL() + +Decodes a received message, passing back the decoded content in the form of a +CSuplMessageBase derived object. The calling code receives ownership of this +object and is responsible for its destruction. + +@param aBuf buffer from which the ASN1 message is to be decoded +@param aError on return, indicates error. KErrNone otherwise. +@return pointer to the decoded SUPL message. +*/ +EXPORT_C CSuplMessageBase* CSuplAsn1DecoderImpl::DecodeL(const TPtrC8* aBuf, TInt& aError) + { + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::DecodeL() Begin\n"); + aError = KErrNone; + + // Log the encoded ASN1 + SUPLLOG(ELogP8, "<- SUPL MESSAGE RECEIVED (HEX)\n"); + SUPLLOGHEX(ELogP8, aBuf->Ptr(), aBuf->Length()); + + // buffer pointer, fixed max length + OSOCTET* msgBuf = (OSOCTET*)aBuf->Ptr(); + TInt len = aBuf->Length(); + + // Create the message decode buffer + ASN1Context* context = new (ELeave) ASN1Context; + CleanupDeletePushL(context); + iDecodeBuffer = new (ELeave) ASN1PERDecodeBuffer (msgBuf, len, FALSE, context); + // construction of iDecodeBuffer successful, pop context off the cleanup stack + CleanupStack::Pop(context); + + // Create data and control objects to manage the decode + iData = new (ELeave) ASN1T_ULP_PDU(); + + // The 'new' above does not initialise member valuables. + // Need to do it manually. (include INC136464) + iData->message.t = 0; + iData->message.u.msSUPLINIT = NULL; + iData->message.u.msSUPLSTART = NULL; + iData->message.u.msSUPLRESPONSE = NULL; + iData->message.u.msSUPLPOSINIT = NULL; + iData->message.u.msSUPLPOS = NULL; + iData->message.u.msSUPLEND = NULL; + iData->message.u.msSUPLAUTHREQ = NULL; + iData->message.u.msSUPLAUTHRESP = NULL; + + iControl = new (ELeave) ASN1C_ULP_PDU (*iDecodeBuffer, *iData); + + // Decode the contents of the message buffer + iControl->Decode(); + + // check for errors + TInt stat = iControl->getStatus(); + if (stat == 0) + { + stat = AdditionalMessageValidation(); + } + if (stat != 0) + { + aError = ProcessAsn1Error(stat); + // delete all objects before return null + delete iDecodeBuffer; + iDecodeBuffer = NULL; + delete iData; + iData = NULL; + delete iControl; + iControl = NULL; + + return NULL; + } + + // build the appropriate LBS SUPL Message Type, and return. + TInt messageType = iData->message.t; + CSuplMessageBase* aMessage; + switch (messageType) + { + case T_UlpMessage_msSUPLINIT: + { + aMessage = CSuplInit::NewL(); + CleanupStack::PushL(aMessage); + break; + } + case T_UlpMessage_msSUPLRESPONSE: + { + aMessage = CSuplResponse::NewL(); + CleanupStack::PushL(aMessage); + break; + } + case T_UlpMessage_msSUPLPOS: + { + aMessage = CSuplPos::NewL(EFalse); + CleanupStack::PushL(aMessage); + break; + } + case T_UlpMessage_msSUPLEND: + { + aMessage = CSuplEnd::NewL(EFalse); + CleanupStack::PushL(aMessage); + break; + } + default: + { + // unexpected message type + aError = KErrNotSupported; + // delete all objects before return null + delete iDecodeBuffer; + iDecodeBuffer = NULL; + delete iData; + iData = NULL; + delete iControl; + iControl = NULL; + + return NULL; + } + } + + // Pass ownership of decoded data to the message object + aMessage->SetDecodedData(iData, iControl); + iControl = NULL; + iData = NULL; + + // delete the decode buffer object + delete iDecodeBuffer; + iDecodeBuffer = NULL; + + // Decode the content of encapsulated positioning method + if (messageType == T_UlpMessage_msSUPLPOS) + { + CSuplPos* posMessage = (CSuplPos*)aMessage; + posMessage->DecodePosPayloadL(aError); + } + + // store un-decoded SUPL INIT message for ver hash calculation + if (messageType == T_UlpMessage_msSUPLINIT) + { + CSuplInit* initMessage = (CSuplInit*)aMessage; + initMessage->SetReceivedMessageL(*aBuf); + } + + // LOG the received message + SUPLLOG(ELogP9, "<- SUPL MESSAGE RECEIVED AND DECODED\n"); + aMessage->LogMessageContent(); + + // pop the constructed message off the stack and return to caller. + CleanupStack::Pop(aMessage); + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::DecodeL() End\n"); + return aMessage; + } + +/** +Translates error codes returned by the ASN1 runtime library to distinguish +from Symbian global error codes. + +Errors are simply translated to positive error codes. They maintain their +meaning as described in rtxErrCodes.h and asn1ErrCodes.h, with the exception +of RTERR_NOMEM is translated to global error code KErrNoMemory. + +@see rtxErrCodes.h +@see asn1ErrCodes.h +*/ +TInt CSuplAsn1DecoderImpl::ProcessAsn1Error(TInt aError) + { + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::ProcessAsn1Error() Begin\n"); + if (aError == RTERR_NOMEM) + { + SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::ProcessAsn1Error() End (Out Of Memory)\n"); + return KErrNoMemory; + } + else + { + SUPLLOG2(ELogP1, "CSuplAsn1DecoderImpl::ProcessAsn1Error() End (ASN1 Runtime Error %d)\n", aError); + return aError * -1; + } + } + +/** +Check for additional errors in messages that +the control object cannot report for +various reasons. +This method returns error codes defined by the asn1 +compiler supplier. +*/ +TInt CSuplAsn1DecoderImpl::AdditionalMessageValidation() +{ + TInt stat = 0; + + // Set Session Id is mandatory in every + // received message. Its absence is not flagged + // by the controller because it is an optional + // parameter in some outgoing messages. + if (!iData->sessionID.m.slpSessionIDPresent) + { + stat = RTERR_SETMISRQ; + } + + return stat; +} +