networkprotocolmodules/common/suplrrlpasn1/src/suplasn1decoderimpl.cpp
changeset 0 9cfd9a3ee49c
--- /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;
+}
+