wapstack/wapmessageapi/sws/CLWSPPduHandler.cpp
branchRCL_3
changeset 65 630d2f34d719
equal deleted inserted replaced
61:17af172ffa5f 65:630d2f34d719
       
     1 // Copyright (c) 2003-2010 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 //
       
    15 
       
    16 #include "OstTraceDefinitions.h"
       
    17 #ifdef OST_TRACE_COMPILER_IN_USE
       
    18 #include "CLWSPPduHandlerTraces.h"
       
    19 #endif
       
    20 
       
    21 #include "CLWSPPduHandler.h"
       
    22 #include "wapmsgerr.h"
       
    23 
       
    24 void CCLWSPPduHandler::UnpackWSPPduL(HBufC8* aWSPPdu, TWSPPduType& aType, HBufC8*& aWSPHeader, HBufC8*& aBody, TUint8& aId, TWSPStatus& aStatus)
       
    25 /** 
       
    26 Unpack the received WSP PDU from remote peer to several data structure expected by the client.
       
    27 @internalComponent
       
    28 @released 
       
    29 @since v8.0 
       
    30 @param aWSPPdu the received WSP PDU from the remote peer. 
       
    31 @param aType the type of the received WSP PDU.
       
    32 @param aWSPHeader the WSP header of the received WSP PDU.
       
    33 @param aBody the data body of the received WSP PDU.
       
    34 @param aId the transaction ID or Push ID of the received WSP PDU.
       
    35 @param aStatus the WSP status of the received WSP PDU.
       
    36 @returns TInt KErrNone on successful completion, or one of the system error codes on failure.
       
    37 */
       
    38 	{
       
    39 	TPtr8 des=aWSPPdu->Des();
       
    40 	if(des.Length() < KPDUTransactionIDAndPDUTypeLength)
       
    41 	{
       
    42         OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CCLWSPPDUHANDLER_UNPACKWSPPDUL_1, "CCLWSPPduHandler::UnpackWSPPduL() Corrupted InComing Wsp PDU");
       
    43         User::Leave(KErrCorrupt);
       
    44 	}
       
    45 	aId=des[KPDUHeaderTransactionIDOffSet];
       
    46 	aType=TWSPPduType(des[KPDUHeaderWSPPDUTypeOffSet]);
       
    47 	switch (aType)
       
    48 		{
       
    49 	case EReply:
       
    50 		UnpackReplyPduL(aWSPPdu, aWSPHeader, aBody, aStatus);
       
    51 		break;
       
    52 	case EPush:
       
    53 		UnpackPushPduL(aWSPPdu, aWSPHeader, aBody);
       
    54 		break;
       
    55 	default:
       
    56 		OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CCLWSPPDUHANDLER_UNPACKWSPPDUL_2, "CCLWSPPduHandler::UnpackWSPPduL() Unknown InComing Wsp PDU Type");
       
    57 		User::Leave(KErrCorrupt);
       
    58 		}
       
    59 	}
       
    60 
       
    61 void CCLWSPPduHandler::PackWSPPduL(HBufC8*& aWSPPdu, TWSPPduType aType, const TDesC& aURI, const TDesC8& aWSPHeader, const TDesC8& aBody, const TUint8 aId)
       
    62 /** 
       
    63 Pack the information to be sent into WSP PDU.
       
    64 @internalComponent
       
    65 @released 
       
    66 @since v8.0 
       
    67 @param aWSPPdu the WSP PDU that is to sent 
       
    68 @param aType the WSP PDU type(the method is to be invoked) 
       
    69 @param aURI  the URI where the WSP PDU goes
       
    70 @param aWSPHeader the WSP header
       
    71 @param aBody the data body
       
    72 @param aId the transaction ID
       
    73 @returns TInt KErrNone on successful completion, or one of the system error codes on failure.
       
    74 */
       
    75 	{
       
    76 	switch (aType)
       
    77 		{
       
    78 	case EGet:
       
    79 	case EGetOptions:
       
    80 	case EGetHead:
       
    81 	case EGetDelete:
       
    82 	case EGetTrace:
       
    83 		PackGetPduL(aWSPPdu, aType, aURI, aWSPHeader, aId);
       
    84 		break;
       
    85 	
       
    86 	case EPost:
       
    87 	case EPostPut:
       
    88 		PackPostPduL(aWSPPdu, aType, aURI, aWSPHeader, aBody, aId);
       
    89 		break;
       
    90 
       
    91 	default:
       
    92 	    OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CCLWSPPDUHANDLER_PACKWSPPDUL_1, "CCLWSPPduHandler::PackWSPPduL() Unknown Method Invoke Wsp PDU Type");
       
    93 	    User::Leave(Wap::EWspClParameterError);
       
    94 		}
       
    95 	}
       
    96 
       
    97 void CCLWSPPduHandler::UnpackPushPduL(HBufC8* aWSPPdu, HBufC8*& aWSPHeader, HBufC8*& aBody)
       
    98 /**
       
    99 Unpack the WSP PUSH PDU.
       
   100 @internalComponent
       
   101 @released 
       
   102 @since v8.0 
       
   103 @param aWSPPdu the received WSP PDU from the remote peer. 
       
   104 @param aWSPHeader the WSP header of the received WSP PDU.
       
   105 @param aBody the data body of the received WSP PDU.
       
   106 @returns TInt KErrNone on successful completion, or one of the system error codes on failure.
       
   107 */
       
   108 	{
       
   109 	TPtrC8 pduBuffer(*aWSPPdu);
       
   110 	TUint32 pduLength=pduBuffer.Length();
       
   111 	TUint32 headerLength(0);
       
   112 	TInt uintvarLength(0);
       
   113 
       
   114 	// if uintvarLength less than KErrNone, then it is a error code.
       
   115 	if ((uintvarLength=UintVar(headerLength, pduBuffer, KPDUTransactionIDAndPDUTypeLength))<KErrNone)
       
   116 		{
       
   117 		User::Leave(uintvarLength);
       
   118 		}
       
   119  	TInt32 bodyLength= pduLength-KPDUTransactionIDAndPDUTypeLength-uintvarLength-headerLength;
       
   120 	if (bodyLength<0)
       
   121 		{
       
   122 		User::Leave(KErrCorrupt);
       
   123 		}
       
   124 	// Extract the WSP Header.
       
   125 	aWSPHeader=HBufC8::NewL(headerLength);
       
   126 	TPtr8 headerDes=aWSPHeader->Des();
       
   127 	headerDes.Copy(pduBuffer.Mid(KPDUTransactionIDAndPDUTypeLength+uintvarLength, headerLength));
       
   128 	// Extract the WSP data body.
       
   129 	aBody=HBufC8::NewL(bodyLength);
       
   130 	TPtr8 bodyDes=aBody->Des();
       
   131 	bodyDes.Copy(pduBuffer.Mid(KPDUTransactionIDAndPDUTypeLength+uintvarLength+headerLength));
       
   132 	}
       
   133 
       
   134 void CCLWSPPduHandler::UnpackReplyPduL(HBufC8* aWSPPdu, HBufC8*& aWSPHeader, HBufC8*& aBody, TWSPStatus& aStatus)
       
   135 /**
       
   136 Unpack the WSP Reply PDU.
       
   137 @internalComponent
       
   138 @released 
       
   139 @since v8.0 
       
   140 @param aWSPPdu the received WSP PDU from the remote peer. 
       
   141 @param aWSPHeader the WSP header of the received WSP PDU.
       
   142 @param aBody the data body of the received WSP PDU.
       
   143 @param aStatus the WSP status of the received WSP PDU.  
       
   144 @returns TInt KErrNone on successful completion, or one of the system error codes on failure.
       
   145 */
       
   146 	{
       
   147 	TPtrC8 pduBuffer(*aWSPPdu);
       
   148 	TUint32 pduLength=pduBuffer.Length();
       
   149 
       
   150 	//Extract the WSP status
       
   151 	aStatus=pduBuffer[KPDUTransactionIDAndPDUTypeLength];
       
   152 
       
   153 	TUint32 headerLength(0);
       
   154 	TInt uintvarLength(0);
       
   155 	// if uintvarLength less than KErrNone, then it is a error code.
       
   156 	if ((uintvarLength=UintVar(headerLength, pduBuffer, KPDUTransactionIDAndPDUTypeLength+KWSPStatusLength))<KErrNone)
       
   157 		{
       
   158 		User::Leave(uintvarLength);
       
   159 		}
       
   160 		
       
   161 	TInt32 bodyLength= pduLength-KPDUTransactionIDAndPDUTypeLength-KWSPStatusLength-uintvarLength-headerLength;
       
   162 	if (bodyLength<0)
       
   163 		{
       
   164 		User::Leave(KErrCorrupt);
       
   165 		}
       
   166 		
       
   167 	// Extract the WSP Header.
       
   168 	aWSPHeader=HBufC8::NewL(headerLength);
       
   169 	TPtr8 headerDes=aWSPHeader->Des();
       
   170 	headerDes.Copy(pduBuffer.Mid(KPDUTransactionIDAndPDUTypeLength+KWSPStatusLength+uintvarLength, headerLength));
       
   171 
       
   172 	// Extract the WSP data body.
       
   173 	aBody=HBufC8::NewL(bodyLength);
       
   174 	TPtr8 bodyDes=aBody->Des();
       
   175 	bodyDes.Copy(pduBuffer.Mid(KPDUTransactionIDAndPDUTypeLength+KWSPStatusLength+uintvarLength+headerLength));
       
   176 	}
       
   177 
       
   178 void CCLWSPPduHandler::PackPostPduL(HBufC8*& aWSPPdu, TWSPPduType aType, const TDesC& aURI, const TDesC8& aWSPHeader, const TDesC8& aBody, const TUint8 aId)
       
   179 /** 
       
   180 Pack the WSP Post PDU.
       
   181 @internalComponent
       
   182 @released 
       
   183 @since v8.0 
       
   184 @param aWSPPdu the WSP PDU that is to sent 
       
   185 @param aType the WSP PDU type(the method is to be invoked) 
       
   186 @param aURI the URI where the WSP PDU goes
       
   187 @param aWSPHeader the WSP header
       
   188 @param aBody the data body
       
   189 @param aId the transaction ID
       
   190 @returns TInt KErrNone on successful completion, or one of the system error codes on failure.
       
   191 */
       
   192 	{
       
   193 	//Convert the URI length to Varible length unsigned integer
       
   194 	TUint32 uriLength=aURI.Length();
       
   195 	HBufC8* uriLengthDes=UintVarL(uriLength);
       
   196 
       
   197 	//Convert the URI length to Varible length unsigned integer
       
   198 	TUint32 headerLength=aWSPHeader.Length();
       
   199 	HBufC8* headerLengthDes=UintVarL(headerLength);
       
   200 
       
   201 	// Calculate the pdu length
       
   202 	TUint32 pduLength = KPDUTransactionIDAndPDUTypeLength+
       
   203 						uriLengthDes->Length()+
       
   204 						headerLengthDes->Length()+
       
   205 						uriLength+
       
   206 						headerLength+
       
   207 						aBody.Length();
       
   208 
       
   209 	//Build the PDU.
       
   210 	aWSPPdu = HBufC8::NewL(pduLength);
       
   211 	TPtr8 pduPtr(aWSPPdu->Des());
       
   212 	pduPtr.Append(aId);
       
   213 	pduPtr.Append(aType);
       
   214 	pduPtr.Append(*uriLengthDes);
       
   215 	pduPtr.Append(*headerLengthDes);
       
   216 	pduPtr.Append(aURI);
       
   217 	pduPtr.Append(aWSPHeader);
       
   218 	pduPtr.Append(aBody);
       
   219 
       
   220 	// delete the temporary buffers
       
   221 	delete uriLengthDes;
       
   222 	delete headerLengthDes;
       
   223 	}
       
   224 void CCLWSPPduHandler::PackGetPduL(HBufC8*& aWSPPdu, TWSPPduType aType, const TDesC& aURI, const TDesC8& aWSPHeader, const TUint8 aId)
       
   225 /** 
       
   226 Pack the WSP Get PDU.
       
   227 @internalComponent
       
   228 @released 
       
   229 @since v8.0 
       
   230 @param aWSPPdu the WSP PDU that is to sent 
       
   231 @param aType the WSP PDU type(the method is to be invoked) 
       
   232 @param aURI the URI where the WSP PDU goes
       
   233 @param aWSPHeader the WSP header
       
   234 @param aId the transaction ID
       
   235 @returns KErrNone on successful completion, or one of the system error codes on failure.
       
   236 */
       
   237 	{
       
   238 
       
   239 	//Convert the URI length to Varible length unsigned integer
       
   240 	TUint32 uriLength=aURI.Length();
       
   241 	HBufC8* uriLengthDes=UintVarL(uriLength);
       
   242 
       
   243 	// Calculate the pdu length
       
   244 	TUint32 pduLength =	KPDUTransactionIDAndPDUTypeLength+
       
   245 						uriLengthDes->Length()+
       
   246 						uriLength+
       
   247 						aWSPHeader.Length();
       
   248 
       
   249 	// Build the PDU.
       
   250 	aWSPPdu = HBufC8::NewL(pduLength);
       
   251 	TPtr8 pduPtr(aWSPPdu->Des());
       
   252 	pduPtr.Append(aId);
       
   253 	pduPtr.Append(aType);
       
   254 	pduPtr.Append(*uriLengthDes);
       
   255 	pduPtr.Append(aURI);
       
   256 	pduPtr.Append(aWSPHeader);
       
   257 	
       
   258 	//Delete the temporary buffer
       
   259 	delete uriLengthDes;
       
   260 	}
       
   261 TInt CCLWSPPduHandler::UintVar(TUint32& aVal, TPtrC8& aBuffer, TUint aOffset)
       
   262 /** 
       
   263 Decode the variable length Unsigned integer to TUint32
       
   264 @internalComponent
       
   265 @released 
       
   266 @since v8.0 
       
   267 @param aVal the value of the variable length Unsigned integer
       
   268 @param aBuffer the descriptor that contains the variable length Unsigned integer
       
   269 @param aOffset the offset of the variable length Unsigned integer
       
   270 @returns one of the system error codes on failure, or the size of variable length Unsigned integer.
       
   271 */
       
   272 	{
       
   273 	// have we run out of buffer?
       
   274 	if (aOffset >= (TUint)aBuffer.Length())
       
   275 		{
       
   276 		return KErrCorrupt;
       
   277 		}
       
   278 		
       
   279 	// maximum length for a uintvar is 5
       
   280 	TInt lenLeft = Min(aBuffer.Mid(aOffset).Length(), KMaxUintVarLength);
       
   281 
       
   282 	// get the first octet
       
   283 	TUint8 byte = aBuffer[aOffset++];
       
   284 	TInt numBytes = 1;
       
   285 	--lenLeft;
       
   286 
       
   287 	// Check if any of the top 3 bits, ignoring the very top 'continue' bit, are set.  
       
   288 	// Later if we see that this is a 5 byte number - we'll know it is corrupt.  
       
   289 	// Encoding uses 7 bits/number 7x5=35 and we only support a maxiumum number 
       
   290 	// of 32 bits.
       
   291 	TBool topThreeBitsSet = byte & KTop3BitSet; 
       
   292 
       
   293 	// copy over data from the byte into our return value (the top bit is a carry bit)
       
   294 	aVal = byte & KWapQuote;
       
   295 
       
   296 	// while the 'continue' bit is set and we have more data
       
   297 	while ((byte & KCarryBitMask) && (lenLeft > 0))
       
   298 		{
       
   299 		// shift our last value up
       
   300 		aVal <<= KUIntVarOctetShift;
       
   301 		// get the next byte
       
   302 		byte = aBuffer[aOffset++];
       
   303 		// copy it over to the lowest byte
       
   304 		aVal |= byte & KWapQuote;
       
   305 		--lenLeft;
       
   306 		++numBytes;
       
   307 		} 
       
   308 
       
   309 	// last octet has continue bit set ... NOT allowed Or
       
   310 	// this was encoded wrong - can't have a number bigger than 32 bits
       
   311 	if ((byte & KCarryBitMask) || (numBytes == 5 && topThreeBitsSet))
       
   312 		{
       
   313 		return KErrCorrupt;
       
   314 		}
       
   315 	// number of bytes read
       
   316 	return numBytes;
       
   317 
       
   318 	}
       
   319 
       
   320 HBufC8* CCLWSPPduHandler::UintVarL(const TUint32 aInt)
       
   321 /** 
       
   322 Encode the TUint32 to the variable length Unsigned integer
       
   323 @internalComponent
       
   324 @released 
       
   325 @since v8.0 
       
   326 @param aInt the length of the data
       
   327 @returns the descriptor that contains the variable length Unsigned integer
       
   328 */
       
   329 	{
       
   330 	TUint8 size = 0; // maximum value is 5 with a 32bit integer
       
   331 	TUint32 value=aInt;
       
   332 	do {
       
   333 		++size;
       
   334 		value >>=KUIntVarOctetShift; ; // shift by 7 bits.
       
   335 		} while (value>0);
       
   336 
       
   337 	HBufC8* output = HBufC8::NewL(size);
       
   338 	TPtr8 outPtr(output->Des());
       
   339 
       
   340 	TInt ii = size; 
       
   341 	while (--ii > 0)
       
   342 		{
       
   343 		outPtr.Append( (TUint8)(aInt>>(KUIntVarOctetShift*(ii))  & KWapQuote) | KCarryBitMask); 
       
   344 		} 
       
   345 
       
   346 	// Finally the first 7 bits, last octet, do not set first bit.
       
   347 	outPtr.Append( (TUint8)(aInt & KWapQuote) ); // Add even if 0 value.
       
   348 
       
   349 	return output;
       
   350 	}