|
1 // Copyright (c) 1997-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 <networking/in_std.h> |
|
17 #include <in_sock.h> |
|
18 #include "VJLOG.H" |
|
19 #include "VJ.H" |
|
20 |
|
21 CVJDeCompressor::CVJDeCompressor() |
|
22 { |
|
23 } |
|
24 |
|
25 void CVJDeCompressor::ConstructL( CVJCompFactory* aFactory, TUint aMaxSlot) |
|
26 /** |
|
27 Construct the CVJDeCompressor object. |
|
28 |
|
29 @param aFactory Factory that created this object |
|
30 @param aMaxSlot Value of the highest VJ connection number to be received |
|
31 */ |
|
32 { |
|
33 // |
|
34 // Note that aMaxSlot is the index of the maximum slot that will be accessed. |
|
35 // |
|
36 __ASSERT_DEBUG(aMaxSlot <= KMaxVjSlot, User::Panic(_L("VJ Panic"), 0)); |
|
37 iNumVJSlots = aMaxSlot; |
|
38 iRxStates = new (ELeave) TVJCompHdr[aMaxSlot+1]; |
|
39 iFactory = aFactory; |
|
40 iFactory->Open(); |
|
41 } |
|
42 |
|
43 CVJDeCompressor::~CVJDeCompressor() |
|
44 { |
|
45 delete []iRxStates; |
|
46 if (iFactory) |
|
47 { |
|
48 iFactory->Close(); |
|
49 } |
|
50 } |
|
51 |
|
52 void CVJDeCompressor::CRCError() |
|
53 /** |
|
54 Sets the discard flag after receiving a bad frame so that future |
|
55 decompressed packets don't get out of sync. |
|
56 */ |
|
57 { |
|
58 LOG(_LIT(string1,"CRC Error");) |
|
59 LOG(Log::Write(string1);) |
|
60 SetFlag(KVJDiscard); |
|
61 } |
|
62 |
|
63 void CVJDeCompressor::CopyRecvHeader(const TUint aConnection, ThdrIP* aHeader) |
|
64 /** |
|
65 Caches a TCP/IP Header to be used as a reference to |
|
66 reconstruct future compressed headers. |
|
67 |
|
68 @param aConnection Valid VJ connection number |
|
69 @param aHeader TCP/IP header |
|
70 */ |
|
71 { |
|
72 __ASSERT_DEBUG(aConnection <= iNumVJSlots, User::Panic(_L("VJ Panic"), 0)); |
|
73 iRxStates[aConnection].StoreTCPIPHeader(aHeader); |
|
74 } |
|
75 |
|
76 void CVJDeCompressor::GetStoredRxHeader(const TUint aConnection, ThdrIP* aIPHeader, ThdrTCP* aTCPHeader) |
|
77 /** |
|
78 Retrieves a packet header from the VJ connection cache. |
|
79 |
|
80 @param aConnection Valid VJ connection number to retrieve |
|
81 @param aIPHeader IP packet header |
|
82 @param aTCPHeader TCP header |
|
83 */ |
|
84 { |
|
85 __ASSERT_DEBUG(aConnection <= iNumVJSlots, User::Panic(_L("VJ Panic"), 0)); |
|
86 iRxStates[aConnection].RetrieveTCPIPHeader(aIPHeader, aTCPHeader); |
|
87 } |
|
88 |
|
89 |
|
90 TBool CVJDeCompressor::CheckStoredRxHeader(const TUint aConnection) const |
|
91 /** |
|
92 Checks if the given VJ connection number has previously been filled in. |
|
93 |
|
94 @param aConnection Valid VJ connection number to check |
|
95 |
|
96 @return ETrue if CopyRecvHeader() has previously been called |
|
97 on this connection number |
|
98 */ |
|
99 { |
|
100 __ASSERT_DEBUG(aConnection <= iNumVJSlots, User::Panic(_L("VJ Panic"), 0)); |
|
101 return iRxStates[aConnection].IsValid(); |
|
102 } |
|
103 |
|
104 |
|
105 TBool CVJDeCompressor::DecompVJComp(RMBufChain& aPacket) |
|
106 /** |
|
107 Decompresses a VJ compressed packet in place. |
|
108 |
|
109 @param aPacket MBuf chain containing packet |
|
110 |
|
111 @return ETrue if the frame was successfully decompressed |
|
112 |
|
113 @see DecompVJUncomp |
|
114 */ |
|
115 { |
|
116 TBool RetCode = EFalse; |
|
117 TUint8 Connection; |
|
118 TUint16 CurrentFrameLength; |
|
119 |
|
120 TUint8* const InitialHeaderPtr = GetVJPtr(aPacket, &CurrentFrameLength); |
|
121 TUint8 Changes = *InitialHeaderPtr; |
|
122 TUint Offset = 1; |
|
123 |
|
124 if (Changes & KVjCompMaskConn) |
|
125 { |
|
126 Connection = *(InitialHeaderPtr+Offset); |
|
127 Offset++; |
|
128 if (Connection <= iNumVJSlots && CheckStoredRxHeader(Connection)) |
|
129 { |
|
130 LOG(_LIT(string1,"Clear error comp");) |
|
131 LOG(Log::Write(string1);) |
|
132 ClearFlag(KVJDiscard); |
|
133 iLastRxConn = Connection; |
|
134 } |
|
135 else |
|
136 { |
|
137 // |
|
138 // The received connection number was invalid. |
|
139 // Ignore all further Compressed frames until an Uncompressed frame |
|
140 // or a frame containing an explicit connection number is received |
|
141 // |
|
142 LOG(_LIT(string1,"Invalid connection");) |
|
143 LOG(Log::Write(string1);) |
|
144 SetFlag(KVJDiscard); |
|
145 return RetCode; |
|
146 } |
|
147 } |
|
148 else |
|
149 { |
|
150 if(TestFlag(KVJDiscard)) |
|
151 { |
|
152 return RetCode; |
|
153 } |
|
154 Connection = (TUint8)iLastRxConn; |
|
155 } |
|
156 |
|
157 TRAPD(ret, DecompressFrameL(aPacket, Connection, Changes, InitialHeaderPtr, Offset, CurrentFrameLength)); |
|
158 if (ret == KErrNone) |
|
159 { |
|
160 // |
|
161 // Under all other circumstances the frame is thrown away |
|
162 // |
|
163 RetCode = ETrue; |
|
164 } |
|
165 |
|
166 return RetCode; |
|
167 } |
|
168 |
|
169 TBool CVJDeCompressor::DecompVJUncomp(RMBufChain& aPacket) |
|
170 /** |
|
171 Handles a VJ uncompressed packet. |
|
172 Stores the packet header in the appropriate VJ connection slot. |
|
173 |
|
174 @param aPacket MBuf chain containing packet |
|
175 |
|
176 @return ETrue if the frame was successfully processed |
|
177 |
|
178 @see DecompVJComp |
|
179 */ |
|
180 { |
|
181 TBool RetCode = EFalse; |
|
182 |
|
183 // |
|
184 // When we get here, the first packet is some information thing, |
|
185 // we want the IPHeader this was the easiest way I could see to do it |
|
186 // |
|
187 // |
|
188 ThdrIP* IPHeader = GetIPHeader(aPacket); |
|
189 |
|
190 if (IPHeader == NULL) |
|
191 { |
|
192 // |
|
193 // The packet was too short. |
|
194 // Ignore all further Compressed frames until an Uncompressed frame |
|
195 // or a frame containing an explicit connection number is received |
|
196 // |
|
197 LOG(_LIT(string1,"Short VJ frame received");) |
|
198 LOG(Log::Write(string1);) |
|
199 SetFlag(KVJDiscard); |
|
200 |
|
201 RetCode = EFalse; |
|
202 } |
|
203 else |
|
204 { |
|
205 TUint ConnectionNumber = IPHeader->NetGetProtocol(); |
|
206 |
|
207 if (ConnectionNumber <= iNumVJSlots) |
|
208 { |
|
209 // |
|
210 // Set the real protocol header to TCP |
|
211 // |
|
212 IPHeader->NetSetProtocol(KProtocolInetTcp); |
|
213 |
|
214 iLastRxConn = ConnectionNumber; |
|
215 LOG(_LIT(string1,"Clear error uncomp");) |
|
216 LOG(Log::Write(string1);) |
|
217 ClearFlag(KVJDiscard); |
|
218 |
|
219 // |
|
220 // Copy the header into one of our connection things |
|
221 // and zero the checksum |
|
222 // |
|
223 CopyRecvHeader(ConnectionNumber, IPHeader); |
|
224 |
|
225 // |
|
226 // Receive this frame properly |
|
227 // |
|
228 RetCode = ETrue; |
|
229 } |
|
230 else |
|
231 { |
|
232 // |
|
233 // The received connection number was invalid. |
|
234 // Ignore all further Compressed frames until an Uncompressed frame |
|
235 // or a frame containing an explicit connection number is received |
|
236 // |
|
237 LOG(_LIT(string1,"Invalid VJ connection received");) |
|
238 LOG(Log::Write(string1);) |
|
239 SetFlag(KVJDiscard); |
|
240 |
|
241 RetCode = EFalse; |
|
242 } |
|
243 } |
|
244 |
|
245 |
|
246 return RetCode; |
|
247 |
|
248 } |
|
249 |
|
250 void CVJDeCompressor::DecompressFrameL(RMBufChain& aPacket, |
|
251 TUint8 aConnection, |
|
252 TUint8 aChanges, |
|
253 TUint8* const aInitialHeaderPtr, |
|
254 TUint aOffset, |
|
255 TUint16 aCurrentFrameLength) |
|
256 /** |
|
257 Uncompresses a VJ compressed TCP/IP header. |
|
258 |
|
259 @param aPacket MBuf chain containing packet to be updated |
|
260 @param aConnection VJ connection number |
|
261 @param aChanges The VJ change mask |
|
262 @param aInitialHeaderPtr Beginning of the compressed VJ header |
|
263 @param aOffset Offset from start of packet to TCP checksum field |
|
264 @param aCurrentFrameLength Length of the compressed packet |
|
265 |
|
266 @leave KErrCorrupt if aPacket is corrupt |
|
267 */ |
|
268 { |
|
269 TUint8* VJCompHeader = aInitialHeaderPtr + aOffset; |
|
270 |
|
271 TUint16 Checksum = BigEndian::Get16(VJCompHeader); |
|
272 VJCompHeader+=2; |
|
273 |
|
274 // |
|
275 // Use the aConnection number to retrieve the TCP Header and IP Header |
|
276 // |
|
277 ThdrIP IPHeader; |
|
278 ThdrTCP TCPHeader; |
|
279 GetStoredRxHeader(aConnection, &IPHeader, &TCPHeader); |
|
280 |
|
281 TUint16 IPHeaderLength = (TUint16)IPHeader.NetGetHdrLen(); |
|
282 TUint16 TCPHeaderLength = (TUint16)TCPHeader.NetGetHdrLen(); |
|
283 TUint16 PreviousDataLength = (TUint16)(IPHeader.NetGetLength() - IPHeaderLength - TCPHeaderLength); |
|
284 |
|
285 // |
|
286 // Set the actual checksum |
|
287 // |
|
288 TCPHeader.VJSetChecksum(Checksum); |
|
289 |
|
290 // |
|
291 // Set Push if appropriate, otherwise clear it. |
|
292 // |
|
293 DecompPushFlag(aChanges, &TCPHeader); |
|
294 |
|
295 // |
|
296 // Handle the Sequence, Window, Ack, Urgent compressed elements |
|
297 // |
|
298 DecompSWAU(aChanges, &VJCompHeader, &TCPHeader, PreviousDataLength); |
|
299 |
|
300 // |
|
301 // Handle the compressed IP Identification field |
|
302 // |
|
303 DecompIPId(aChanges, &VJCompHeader, &IPHeader); |
|
304 |
|
305 TUint16 OriginalHeaderLength = (TUint16)(VJCompHeader - aInitialHeaderPtr); |
|
306 |
|
307 // |
|
308 // Check if the received frame is shorter than the VJ header, and discard it if |
|
309 // so. This condition is detected by VJCompHeader being incremented beyond the end of |
|
310 // the packet during processing. |
|
311 // |
|
312 if (OriginalHeaderLength > aCurrentFrameLength) |
|
313 { |
|
314 LOG(_LIT(string1,"Short frame discarded");) |
|
315 LOG(Log::Write(string1);) |
|
316 User::Leave(KErrCorrupt); |
|
317 } |
|
318 |
|
319 TUint16 CurrentDataLength = (TUint16)(aCurrentFrameLength - OriginalHeaderLength); |
|
320 |
|
321 IPHeaderLength = (TUint16)IPHeader.NetGetHdrLen(); |
|
322 |
|
323 IPHeader.NetSetLength((TUint16)(CurrentDataLength + IPHeaderLength + TCPHeaderLength)); |
|
324 |
|
325 // |
|
326 // Generate the IP Header Checksum. |
|
327 // |
|
328 DoIPChecksum(&IPHeader, IPHeaderLength); |
|
329 |
|
330 // |
|
331 // Now the hard bit; I have reconstructed the packet, now need |
|
332 // to get it into the right format and receive it. |
|
333 // |
|
334 CopyInNewHeaderL(&aPacket, &IPHeader, &TCPHeader, (VJCompHeader - aInitialHeaderPtr), IPHeaderLength, TCPHeaderLength); |
|
335 |
|
336 //TCPHeader.Printf(); |
|
337 // |
|
338 // Store the rebuilt TCP/IP header for this aConnection |
|
339 // |
|
340 // GetIPHeader will never return NULL here because we check the |
|
341 // packet size above. |
|
342 // |
|
343 CopyRecvHeader(aConnection, GetIPHeader(aPacket)); |
|
344 |
|
345 // |
|
346 // Increment the length in the Info Header |
|
347 // |
|
348 RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPacket); |
|
349 info->iLength += IPHeaderLength + TCPHeaderLength - OriginalHeaderLength; |
|
350 } |
|
351 |
|
352 // TODO: This is a funny place for this declaration |
|
353 void ThdrTCP::Printf() |
|
354 { |
|
355 TInt i; |
|
356 LOG(_LIT(string1,"TCP Header.");) |
|
357 LOG(Log::Write(string1);) |
|
358 LOG(_LIT(string2,"%02x ");) |
|
359 for (i=0;i<20;i++) |
|
360 { |
|
361 LOG(Log::Printf(string2,u.iData8[i]);) |
|
362 } |
|
363 } |
|
364 |
|
365 ThdrIP* CVJDeCompressor::GetIPHeader(RMBufChain &aChain) |
|
366 /** |
|
367 Extracts the IP Header from the packet even though there is a buffer |
|
368 of Info on the front. |
|
369 This is used in VJ, to avoid the awful hack in the main receive path. |
|
370 PRR 20-11-97 |
|
371 |
|
372 @param aChain MBuf chain containing packet |
|
373 |
|
374 @return Pointer to packet data in chain, or NULL if the packet is too short |
|
375 */ |
|
376 { |
|
377 RMBuf* Temp = aChain.Remove(); |
|
378 TUint n = aChain.Align(KInetMaxHeaderSize); |
|
379 ThdrIP* IPHeader = (n<KIPMinHeaderSize) ? NULL : (ThdrIP*)aChain.First()->Ptr(); |
|
380 aChain.Prepend(Temp); |
|
381 return IPHeader; |
|
382 } |
|
383 |
|
384 void CVJDeCompressor::DoIPChecksum(ThdrIP* aIPHeader, TUint16 aIPHeaderLength) |
|
385 /** |
|
386 Calculate the IP checksum and store it in the given IP packet header. |
|
387 See RFC 1071. |
|
388 |
|
389 @param aIPHeader IP packet header |
|
390 @param aIPHeaderLength Length of IP header in bytes (must be even) |
|
391 */ |
|
392 { |
|
393 __ASSERT_DEBUG(!(aIPHeaderLength % 2), User::Panic(_L("VJ Panic"), 0)); // length must be even |
|
394 |
|
395 aIPHeader->VJSetChecksum(0); // Clear the header checksum before calculating |
|
396 |
|
397 TUint16* Ptr = (TUint16*)aIPHeader; |
|
398 TUint32 Checksum=0; |
|
399 TInt i; |
|
400 for (i=aIPHeaderLength; i>0; i-=2) |
|
401 { |
|
402 Checksum += *Ptr++; |
|
403 } |
|
404 |
|
405 // |
|
406 // Take care of the wrapping over 16 bits |
|
407 // Doing it twice is sufficient for IP headers. |
|
408 // |
|
409 Checksum = (Checksum & 0xFFFF) + (Checksum >> 16); |
|
410 Checksum = (Checksum & 0xFFFF) + (Checksum >> 16); |
|
411 Checksum = ~Checksum; |
|
412 |
|
413 // |
|
414 // Do the endian conversion once, after the checksum is calculated |
|
415 // |
|
416 Checksum = BigEndian::Get16((TUint8*)&Checksum); |
|
417 |
|
418 aIPHeader->VJSetChecksum((TUint16)Checksum); |
|
419 } |
|
420 |
|
421 TUint8* CVJDeCompressor::GetVJPtr(RMBufChain &aChain, TUint16* aCurrentFrameLength) |
|
422 /** |
|
423 Gets a pointer to the VJ Header even though there is a pseudo (Adam) buffer of Info on the front. |
|
424 |
|
425 @param aChain MBuf chain containing packet |
|
426 @param aCurrentFrameLength Returns the length of the packet |
|
427 |
|
428 @return Pointer to beginning of packet data |
|
429 */ |
|
430 { |
|
431 RMBuf* Temp = aChain.Remove(); |
|
432 aChain.Align(KInetMaxHeaderSize); |
|
433 TUint8* IPPtr = aChain.First()->Ptr(); |
|
434 |
|
435 *aCurrentFrameLength = (TUint16)aChain.Length(); |
|
436 |
|
437 aChain.Prepend(Temp); |
|
438 return IPPtr; |
|
439 } |
|
440 |
|
441 void CVJDeCompressor::CopyInNewHeaderL(RMBufChain* aPacket, ThdrIP* aIPHeader, ThdrTCP* aTCPHeader, |
|
442 TUint aCompressedHeaderLength, TUint16 aIPHeaderLength, TUint16 aTCPHeaderLength) |
|
443 /** |
|
444 Copy the uncompressed header into the proper location in the packet. |
|
445 |
|
446 @param aPacket MBuf chain containing packet to be updated |
|
447 @param aIPHeader IP packet header |
|
448 @param aTCPHeader TCP header |
|
449 @param aCompressedHeaderLength Length of VJ compression header |
|
450 @param aIPHeaderLength Length of IP header |
|
451 @param aTCPHeaderLength Length of TCP header |
|
452 */ |
|
453 { |
|
454 TUint16 NewHeaderLength = (TUint16)(aIPHeaderLength + aTCPHeaderLength); |
|
455 // |
|
456 // Take the Info thing off |
|
457 // |
|
458 RMBuf* info = aPacket->Remove(); |
|
459 |
|
460 // |
|
461 // Now it is just possible that the frame contains no data |
|
462 // |
|
463 if ( aPacket->Length() == (TInt)aCompressedHeaderLength ) |
|
464 { |
|
465 // |
|
466 // Have finished with the compressed header |
|
467 // |
|
468 aPacket->TrimStart(aCompressedHeaderLength); |
|
469 |
|
470 aPacket->AllocL(NewHeaderLength); |
|
471 |
|
472 } |
|
473 else |
|
474 { |
|
475 // |
|
476 // Have finished with the compressed header |
|
477 // |
|
478 aPacket->TrimStart(aCompressedHeaderLength); |
|
479 |
|
480 // |
|
481 // Make way for the uncompressed header |
|
482 // |
|
483 aPacket->PrependL(NewHeaderLength); |
|
484 } |
|
485 |
|
486 TPtrC8 TempDescIP((TUint8*)aIPHeader, aIPHeaderLength); |
|
487 aPacket->CopyIn(TempDescIP, 0); |
|
488 |
|
489 TPtrC8 TempDescTCP((TUint8*)aTCPHeader, aTCPHeaderLength); |
|
490 aPacket->CopyIn(TempDescTCP, aIPHeaderLength); |
|
491 |
|
492 // |
|
493 // Put the Info header back unchanged; it must be updated by the caller. |
|
494 // |
|
495 aPacket->Prepend(info); |
|
496 } |
|
497 |
|
498 void CVJDeCompressor::DecompSWAU(const TUint aChanges, TUint8** aVJCompHeader, ThdrTCP* aTCPHeader, TUint16 aPreviousFrameLength) |
|
499 /** |
|
500 Decompresses the special case SWAU type packet. |
|
501 |
|
502 @param aChanges The VJ change mask |
|
503 @param aVJCompHeader Pointer to the pointer to the VJ compressed header |
|
504 @param aTCPHeader TCP header to be updated |
|
505 @param aPreviousFrameLength Length of cached packet for this VJ connection |
|
506 */ |
|
507 { |
|
508 TUint32 SequenceNumber; |
|
509 TUint32 AckNumber; |
|
510 |
|
511 switch ( aChanges & KVjCompMaskSpecials ) |
|
512 { |
|
513 case KVjCompMaskSpecialI: // Echoed data e.g. Telnet |
|
514 // |
|
515 // The sequence and acknowledge numbers increment by the data |
|
516 // portion of the frame |
|
517 // |
|
518 |
|
519 SequenceNumber = aTCPHeader->NetGetSeqNum(); |
|
520 aTCPHeader->NetSetSeqNum(SequenceNumber + aPreviousFrameLength); |
|
521 AckNumber = aTCPHeader->NetGetAckNum(); |
|
522 aTCPHeader->NetSetAckNum(AckNumber + aPreviousFrameLength); |
|
523 break; |
|
524 |
|
525 case KVjCompMaskSpecialD: //Unidirectional Data e.g. ftp |
|
526 // |
|
527 // The sequence numbers increment by the data portion of the frame. |
|
528 // |
|
529 SequenceNumber = aTCPHeader->NetGetSeqNum(); |
|
530 aTCPHeader->NetSetSeqNum(SequenceNumber + aPreviousFrameLength); |
|
531 break; |
|
532 |
|
533 default: |
|
534 // |
|
535 // One (or more)of the SWAU bits are set and it's not a special case. |
|
536 // |
|
537 DecompUrgent(aVJCompHeader, aTCPHeader, aChanges); |
|
538 |
|
539 if( aChanges & KVjCompMaskWindow ) |
|
540 { |
|
541 DecompWindow(aVJCompHeader, aTCPHeader); |
|
542 } |
|
543 |
|
544 if( aChanges & KVjCompMaskAck ) |
|
545 { |
|
546 DecompAck(aVJCompHeader, aTCPHeader); |
|
547 } |
|
548 |
|
549 if( aChanges & KVjCompMaskSeq ) |
|
550 { |
|
551 DecompSeq(aVJCompHeader, aTCPHeader); |
|
552 } |
|
553 |
|
554 break; |
|
555 } |
|
556 } |
|
557 |
|
558 void CVJDeCompressor::DecompUrgent(TUint8** aVJCompHeader, ThdrTCP*aTCPHeader, TUint aChanges) |
|
559 /** |
|
560 Decompresses the Urgent field. |
|
561 |
|
562 @param aVJCompHeader Pointer to the pointer to the VJ compressed header |
|
563 @param aTCPHeader TCP header to be updated |
|
564 @param aChanges The VJ change mask |
|
565 */ |
|
566 { |
|
567 TUint Flags = aTCPHeader->VJGetFlags(); |
|
568 |
|
569 if ( aChanges & KVjCompMaskUrgent ) |
|
570 { |
|
571 Flags |= KTcpURG; |
|
572 TUint16 Delta = DecodeDelta(aVJCompHeader); |
|
573 aTCPHeader->NetSetUrgPtr(Delta); |
|
574 } |
|
575 else |
|
576 { |
|
577 Flags &= ~KTcpURG; |
|
578 } |
|
579 |
|
580 aTCPHeader->VJSetFlags(Flags); |
|
581 } |
|
582 |
|
583 void CVJDeCompressor::DecompIPId(const TUint aChanges, TUint8** aVJCompHeader, ThdrIP* aIPHeader) |
|
584 /** |
|
585 Decompresses the IP Identification field. |
|
586 |
|
587 @param aChanges The VJ change mask |
|
588 @param aVJCompHeader Pointer to the pointer to the VJ compressed header |
|
589 @param aIPHeader IP packet header to be updated |
|
590 */ |
|
591 { |
|
592 TUint16 ID; |
|
593 if ( aChanges & KVjCompMaskIp ) |
|
594 { |
|
595 ID = (TUint16)aIPHeader->NetGetId(); |
|
596 ID = (TUint16)(ID + DecodeDelta(aVJCompHeader)); |
|
597 aIPHeader->NetSetId(ID); |
|
598 } |
|
599 else |
|
600 { |
|
601 ID = (TUint16)aIPHeader->NetGetId(); |
|
602 ID++; |
|
603 aIPHeader->NetSetId(ID); |
|
604 } |
|
605 } |
|
606 |
|
607 void CVJDeCompressor::DecompSeq(TUint8** aVJCompHeader, ThdrTCP* aTCPHeader) |
|
608 /** |
|
609 Decompresses the Sequence Number field. |
|
610 |
|
611 @param aVJCompHeader Pointer to the pointer to the VJ compressed header |
|
612 @param aTCPHeader TCP header to be updated |
|
613 */ |
|
614 { |
|
615 TUint16 Delta = DecodeDelta(aVJCompHeader); |
|
616 TUint32 SequenceNumber = aTCPHeader->NetGetSeqNum(); |
|
617 |
|
618 SequenceNumber += Delta; |
|
619 |
|
620 aTCPHeader->NetSetSeqNum(SequenceNumber); |
|
621 } |
|
622 |
|
623 void CVJDeCompressor::DecompAck(TUint8** aVJCompHeader, ThdrTCP* aTCPHeader) |
|
624 /** |
|
625 Decompresses the Acknowledgement Number field. |
|
626 |
|
627 @param aVJCompHeader Pointer to the pointer to the VJ compressed header |
|
628 @param aTCPHeader TCP header to be updated |
|
629 */ |
|
630 { |
|
631 TUint16 Delta = DecodeDelta(aVJCompHeader); |
|
632 TUint32 AckNumber = aTCPHeader->NetGetAckNum(); |
|
633 |
|
634 AckNumber += Delta; |
|
635 |
|
636 aTCPHeader->NetSetAckNum(AckNumber); |
|
637 } |
|
638 |
|
639 |
|
640 void CVJDeCompressor::DecompWindow(TUint8** aVJCompHeader, ThdrTCP* aTCPHeader) |
|
641 /** |
|
642 Decompresses the Window field. |
|
643 |
|
644 @param aVJCompHeader Pointer to the pointer to the VJ compressed header |
|
645 @param aTCPHeader TCP header to be updated |
|
646 */ |
|
647 { |
|
648 TInt16 Delta = DecodeDelta(aVJCompHeader); |
|
649 TUint16 Window = aTCPHeader->NetGetWindow(); |
|
650 |
|
651 LOG(_LIT(string1,"Window %d");) |
|
652 LOG(Log::Printf(string1, Window);) |
|
653 LOG(_LIT(string2,"Window change %d");) |
|
654 LOG(Log::Printf(string2, Delta);) |
|
655 |
|
656 Window = (TUint16)(Delta + Window); |
|
657 LOG(_LIT(string3,"New Window %d");) |
|
658 LOG(Log::Printf(string3, Window);) |
|
659 |
|
660 aTCPHeader->NetSetWindow(Window); |
|
661 } |
|
662 |
|
663 void CVJDeCompressor::DecompPushFlag(const TUint aChanges, ThdrTCP* aTCPHeader) |
|
664 /** |
|
665 Decompresses the Push flag. |
|
666 |
|
667 @param aChanges The VJ change mask |
|
668 @param aTCPHeader TCP header to be updated |
|
669 */ |
|
670 { |
|
671 TUint Flags = aTCPHeader->VJGetFlags(); |
|
672 |
|
673 if ( aChanges & KVjCompMaskPush ) |
|
674 { |
|
675 Flags |= KTcpPSH; |
|
676 } |
|
677 else |
|
678 { |
|
679 Flags &= ~KTcpPSH; |
|
680 } |
|
681 |
|
682 aTCPHeader->VJSetFlags(Flags); |
|
683 } |
|
684 |
|
685 TUint16 CVJDeCompressor::DecodeDelta( TUint8** aVJCompHeader ) |
|
686 /** |
|
687 Decodes a compressed delta value. |
|
688 |
|
689 @param aVJCompHeader Pointer to pointer into VJ header buffer holding encoded value; |
|
690 returns with pointer incremented one past end of value |
|
691 |
|
692 @return Decoded value |
|
693 */ |
|
694 { |
|
695 TUint16 Value = (TUint16) **aVJCompHeader; |
|
696 (*aVJCompHeader)++; |
|
697 |
|
698 if (Value == 0) |
|
699 { |
|
700 // |
|
701 // Zero is an extension; the next two bytes give the 16 bit value |
|
702 // |
|
703 Value = BigEndian::Get16(*aVJCompHeader); |
|
704 *aVJCompHeader += 2; |
|
705 } |
|
706 return Value; |
|
707 } |
|
708 |