45
|
1 |
// Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
|
44
|
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 |
|
45
|
16 |
#include "OstTraceDefinitions.h"
|
|
17 |
#ifdef OST_TRACE_COMPILER_IN_USE
|
|
18 |
#include "CLWSPPduHandlerTraces.h"
|
|
19 |
#endif
|
|
20 |
|
44
|
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 |
{
|
45
|
42 |
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CCLWSPPDUHANDLER_UNPACKWSPPDUL_1, "CCLWSPPduHandler::UnpackWSPPduL() Corrupted InComing Wsp PDU");
|
|
43 |
User::Leave(KErrCorrupt);
|
44
|
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:
|
45
|
56 |
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CCLWSPPDUHANDLER_UNPACKWSPPDUL_2, "CCLWSPPduHandler::UnpackWSPPduL() Unknown InComing Wsp PDU Type");
|
44
|
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:
|
45
|
92 |
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CCLWSPPDUHANDLER_PACKWSPPDUL_1, "CCLWSPPduHandler::PackWSPPduL() Unknown Method Invoke Wsp PDU Type");
|
|
93 |
User::Leave(Wap::EWspClParameterError);
|
44
|
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 |
}
|