--- /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;
+}
+