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