networkprotocolmodules/common/suplrrlpasn1/src/suplasn1decoderimpl.cpp
branchGCC_SURGE
changeset 49 5f20f71a57a3
parent 41 ec40843d536a
parent 45 15a2125aa2f3
equal deleted inserted replaced
41:ec40843d536a 49:5f20f71a57a3
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Internal implementation of the SUPL ASN1 Decoder
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalTechnology
       
    21  
       
    22 */
       
    23 
       
    24 #include "ULP.h"
       
    25 #include "suplasn1decoderimpl.h"
       
    26 #include "suplinit.h"
       
    27 #include "suplresponse.h"
       
    28 #include "suplpos.h"
       
    29 #include "suplend.h"
       
    30 #include "supldevloggermacros.h" 
       
    31 
       
    32 /**
       
    33 Static factory constructor
       
    34 */
       
    35 EXPORT_C CSuplAsn1DecoderImpl* CSuplAsn1DecoderImpl::NewL()
       
    36 	{
       
    37 	SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::NewL() Begin\n");
       
    38 	CSuplAsn1DecoderImpl* self = new (ELeave) CSuplAsn1DecoderImpl();
       
    39 	CleanupStack::PushL(self);
       
    40 	self->ConstructL();
       
    41 	SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::NewL() End\n");
       
    42 	CleanupStack::Pop(self);
       
    43 	return self;
       
    44 	}
       
    45 	
       
    46 /**
       
    47 Constructor
       
    48 */
       
    49 CSuplAsn1DecoderImpl::CSuplAsn1DecoderImpl()
       
    50 	{
       
    51 	}
       
    52 	
       
    53 /**
       
    54 Second stage constructor
       
    55 */
       
    56 void CSuplAsn1DecoderImpl::ConstructL()
       
    57 	{
       
    58 	}
       
    59 
       
    60 /**
       
    61 Destructor
       
    62 */
       
    63 CSuplAsn1DecoderImpl::~CSuplAsn1DecoderImpl()
       
    64 	{
       
    65 	SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::~CSuplAsn1DecoderImpl() Begin\n");
       
    66 	delete iDecodeBuffer;
       
    67 	delete iData;
       
    68 	delete iControl;
       
    69 	// release the STDLIB resources associated with this thread
       
    70 	CloseSTDLIB();
       
    71 	SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::~CSuplAsn1DecoderImpl() End\n");
       
    72 	}
       
    73 
       
    74 /**
       
    75 DecodeL()
       
    76 
       
    77 Decodes a received message, passing back the decoded content in the form of a
       
    78 CSuplMessageBase derived object. The calling code receives ownership of this
       
    79 object and is responsible for its destruction.
       
    80 
       
    81 @param  aBuf   buffer from which the ASN1 message is to be decoded
       
    82 @param  aError on return, indicates error. KErrNone otherwise.
       
    83 @return pointer to the decoded SUPL message.
       
    84 */
       
    85 EXPORT_C CSuplMessageBase* CSuplAsn1DecoderImpl::DecodeL(const TPtrC8* aBuf, TInt& aError)
       
    86 	{
       
    87 	SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::DecodeL() Begin\n");
       
    88 	aError = KErrNone;
       
    89 	
       
    90 	// Log the encoded ASN1	
       
    91 	SUPLLOG(ELogP8, "<- SUPL MESSAGE RECEIVED (HEX)\n");
       
    92 	SUPLLOGHEX(ELogP8, aBuf->Ptr(), aBuf->Length());
       
    93 		
       
    94 	// buffer pointer, fixed max length
       
    95 	OSOCTET* msgBuf = (OSOCTET*)aBuf->Ptr();
       
    96 	TInt len = aBuf->Length();
       
    97 
       
    98 	// Create the message decode buffer
       
    99 	ASN1Context* context = new (ELeave) ASN1Context;
       
   100 	CleanupDeletePushL(context);
       
   101 	iDecodeBuffer = new (ELeave) ASN1PERDecodeBuffer (msgBuf, len, FALSE, context);
       
   102 	// construction of iDecodeBuffer successful, pop context off the cleanup stack
       
   103 	CleanupStack::Pop(context);
       
   104 
       
   105 	// Create data and control objects to manage the decode
       
   106 	iData = new (ELeave) ASN1T_ULP_PDU();
       
   107 	
       
   108 	// The 'new' above does not initialise member valuables.
       
   109  	// Need to do it manually. (include INC136464)
       
   110  	iData->message.t = 0;
       
   111  	iData->message.u.msSUPLINIT = NULL;
       
   112  	iData->message.u.msSUPLSTART = NULL;
       
   113  	iData->message.u.msSUPLRESPONSE = NULL;
       
   114  	iData->message.u.msSUPLPOSINIT = NULL;
       
   115  	iData->message.u.msSUPLPOS = NULL;
       
   116  	iData->message.u.msSUPLEND = NULL;
       
   117  	iData->message.u.msSUPLAUTHREQ = NULL;
       
   118  	iData->message.u.msSUPLAUTHRESP = NULL;
       
   119 	
       
   120 	iControl = new (ELeave) ASN1C_ULP_PDU (*iDecodeBuffer, *iData);
       
   121 	
       
   122 	// Decode the contents of the message buffer
       
   123 	iControl->Decode();
       
   124 	
       
   125 	// check for errors
       
   126 	TInt stat = iControl->getStatus();
       
   127 	if (stat == 0)
       
   128 		{
       
   129 		stat = AdditionalMessageValidation();
       
   130 		}
       
   131 	if (stat != 0)
       
   132 		{
       
   133 		aError = ProcessAsn1Error(stat);
       
   134 		// delete all objects before return null
       
   135         delete iDecodeBuffer;
       
   136         iDecodeBuffer = NULL;
       
   137         delete iData;
       
   138         iData = NULL;
       
   139         delete iControl;
       
   140         iControl = NULL;
       
   141 		
       
   142 		return NULL;
       
   143 		}
       
   144 	
       
   145 	// build the appropriate LBS SUPL Message Type, and return.
       
   146 	TInt messageType = iData->message.t;
       
   147 	CSuplMessageBase* aMessage;
       
   148 	switch (messageType)
       
   149 		{
       
   150 		case T_UlpMessage_msSUPLINIT:
       
   151 			{
       
   152 			aMessage = CSuplInit::NewL();
       
   153 			CleanupStack::PushL(aMessage);
       
   154 			break;
       
   155 			}
       
   156 		case T_UlpMessage_msSUPLRESPONSE:
       
   157 			{
       
   158 			aMessage = CSuplResponse::NewL();
       
   159 			CleanupStack::PushL(aMessage);
       
   160 			break;
       
   161 			}
       
   162 		case T_UlpMessage_msSUPLPOS:
       
   163 			{
       
   164 			aMessage = CSuplPos::NewL(EFalse);
       
   165 			CleanupStack::PushL(aMessage);
       
   166 			break;
       
   167 			}
       
   168 		case T_UlpMessage_msSUPLEND:
       
   169 			{
       
   170 			aMessage = CSuplEnd::NewL(EFalse);
       
   171 			CleanupStack::PushL(aMessage);
       
   172 			break;
       
   173 			}
       
   174 		default:
       
   175 			{
       
   176 			// unexpected message type
       
   177 			aError = KErrNotSupported;
       
   178 			// delete all objects before return null
       
   179             delete iDecodeBuffer;
       
   180             iDecodeBuffer = NULL;
       
   181             delete iData;
       
   182             iData = NULL;
       
   183             delete iControl;
       
   184             iControl = NULL;
       
   185 			
       
   186 			return NULL;
       
   187 			}
       
   188 		}
       
   189 	
       
   190 	// Pass ownership of decoded data to the message object
       
   191 	aMessage->SetDecodedData(iData, iControl);
       
   192 	iControl = NULL;
       
   193 	iData = NULL;
       
   194 	
       
   195 	// delete the decode buffer object
       
   196 	delete iDecodeBuffer;
       
   197 	iDecodeBuffer = NULL;
       
   198 
       
   199 	// Decode the content of encapsulated positioning method
       
   200 	if (messageType == T_UlpMessage_msSUPLPOS)
       
   201 		{
       
   202 		CSuplPos* posMessage = (CSuplPos*)aMessage;
       
   203 		posMessage->DecodePosPayloadL(aError);
       
   204 		}
       
   205 		
       
   206 	// store un-decoded SUPL INIT message for ver hash calculation	
       
   207 	if (messageType == T_UlpMessage_msSUPLINIT)
       
   208 		{
       
   209 		CSuplInit* initMessage = (CSuplInit*)aMessage;
       
   210 		initMessage->SetReceivedMessageL(*aBuf);
       
   211 		}
       
   212 	
       
   213 	// LOG the received message
       
   214 	SUPLLOG(ELogP9, "<- SUPL MESSAGE RECEIVED AND DECODED\n");
       
   215 	aMessage->LogMessageContent();
       
   216 	
       
   217 	// pop the constructed message off the stack and return to caller.
       
   218 	CleanupStack::Pop(aMessage);
       
   219 	SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::DecodeL() End\n");
       
   220 	return aMessage;
       
   221 	}
       
   222 	
       
   223 /**
       
   224 Translates error codes returned by the ASN1 runtime library to distinguish
       
   225 from Symbian global error codes.
       
   226 
       
   227 Errors are simply translated to positive error codes. They maintain their
       
   228 meaning as described in rtxErrCodes.h and asn1ErrCodes.h, with the exception
       
   229 of RTERR_NOMEM is translated to global error code KErrNoMemory.
       
   230 
       
   231 @see rtxErrCodes.h
       
   232 @see asn1ErrCodes.h
       
   233 */
       
   234 TInt CSuplAsn1DecoderImpl::ProcessAsn1Error(TInt aError)
       
   235 	{
       
   236 	SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::ProcessAsn1Error() Begin\n");
       
   237 	if (aError == RTERR_NOMEM)
       
   238 		{
       
   239 		SUPLLOG(ELogP1, "CSuplAsn1DecoderImpl::ProcessAsn1Error() End (Out Of Memory)\n");
       
   240 		return KErrNoMemory;
       
   241 		}
       
   242 	else
       
   243 		{
       
   244 		SUPLLOG2(ELogP1, "CSuplAsn1DecoderImpl::ProcessAsn1Error() End (ASN1 Runtime Error %d)\n", aError);
       
   245 		return aError * -1;
       
   246 		}
       
   247 	}
       
   248 
       
   249 /**
       
   250 Check for additional errors in messages that
       
   251 the control object cannot report for
       
   252 various reasons.
       
   253 This method returns error codes defined by the asn1
       
   254 compiler supplier.
       
   255 */
       
   256 TInt CSuplAsn1DecoderImpl::AdditionalMessageValidation()
       
   257 {
       
   258 	TInt stat = 0;
       
   259 	
       
   260 	// Set Session Id is mandatory in every
       
   261 	// received message. Its absence is not flagged
       
   262 	// by the controller because it is an optional
       
   263 	// parameter in some outgoing messages.
       
   264 	if (!iData->sessionID.m.slpSessionIDPresent)
       
   265 		{
       
   266 		stat = RTERR_SETMISRQ;
       
   267 		}
       
   268 	
       
   269 	return stat;
       
   270 }
       
   271