bthci/hci2implementations/hctls/bcsp/src/hctlbcspframe.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2006-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "hctlbcspframe.h"
       
    22 
       
    23 #include "bcsputils.h"
       
    24 #include "hctlbcspconsts.h"
       
    25 #include "debug.h"
       
    26 
       
    27 const TUint16 KCrcTable[] = 
       
    28 /**
       
    29 	Global CRC table
       
    30 */
       
    31 	{
       
    32 	0x0000, 0x1081, 0x2102, 0x3183,
       
    33 	0x4204, 0x5285, 0x6306, 0x7387,
       
    34 	0x8408, 0x9489, 0xa50a, 0xb58b,
       
    35 	0xc60c, 0xd68d,	0xe70e, 0xf78f
       
    36 	};
       
    37 
       
    38 /**
       
    39 Implementation of Class THctlBcspPacketType
       
    40 */
       
    41 
       
    42 
       
    43 /**
       
    44 	Method to set BCSP ProtocolId
       
    45 */
       
    46 TInt THCTLBcspPacketType::SetProtocolId(TUint8 aProtocolId)
       
    47 	{
       
    48 	LOG_FUNC
       
    49 
       
    50 #ifdef __ARMCC__
       
    51 // Suppressing the warning "Pointless comparison of unsigned integer with zero"
       
    52 // as although a constant may be zero it is present so as to make the code more
       
    53 // understandable.
       
    54 # pragma diag_suppress 186
       
    55 #endif // __ARMCC__
       
    56 
       
    57 	// if (>2 && <5 || >7) then fail
       
    58 if ((aProtocolId > KBcspBcCmdChnl && aProtocolId < KBcspCommEvntChnl) || (aProtocolId > KBcspSynchronousDataChnl))
       
    59 	{
       
    60 	LOG1(_L8("THCTLBcspPacketType: Header unsupported, this used to be a BCSP 6 panic, now error handled. aProtocolId = %d"), aProtocolId);
       
    61 	return KErrNotSupported;
       
    62 	}	               
       
    63 	               
       
    64 #ifdef __ARMCC__
       
    65 # pragma diag_default 186
       
    66 #endif // __ARMCC__
       
    67 
       
    68 	iProtocolId = aProtocolId;
       
    69 	return KErrNone;
       
    70 	}
       
    71 
       
    72 TUint8 THCTLBcspPacketType::ProtocolId() const
       
    73 	{
       
    74 	return iProtocolId;
       
    75 	}
       
    76 
       
    77 /**
       
    78 Implementation of Class THctlBcspFlags
       
    79 */
       
    80 
       
    81 TBool THCTLBcspFlags::CrcEnabled() const
       
    82 	{
       
    83 	return (iFlagsField & KBcspCrcPresentMask);
       
    84 	}
       
    85 
       
    86 TUint8 THCTLBcspFlags::Ack() const
       
    87 	{
       
    88 	return ((iFlagsField & KBcspAckMask) >> KBcspAckFieldOffset);
       
    89 	}
       
    90 
       
    91 TUint8 THCTLBcspFlags::Sequence() const
       
    92 	{
       
    93 	return (iFlagsField & KBcspSeqMask);
       
    94 	}
       
    95 
       
    96 TBool THCTLBcspFlags::IsReliableProtcolType() const
       
    97 	{
       
    98 	return (iFlagsField & KBcspProtocolTypeMask);
       
    99 	}
       
   100 
       
   101 TUint8 THCTLBcspFlags::FlagsField() const
       
   102 	{
       
   103 	return iFlagsField;
       
   104 	}
       
   105 
       
   106 /**
       
   107 	Trivial setter will panic if we attempt to set an invalid value
       
   108 */
       
   109 void THCTLBcspFlags::SetAck(TUint8 aValue) 
       
   110 	{
       
   111 	__ASSERT_DEBUG((aValue < KMaxWindowSize), PANIC(KBcspPanicCat, EBcspInvalidAckValue));
       
   112 	// Clear the existing value and set the new value.
       
   113 	iFlagsField &= ~KBcspAckMask;
       
   114 	iFlagsField |= (aValue << KBcspAckFieldOffset);
       
   115 	}
       
   116 
       
   117 /**
       
   118 	Trivial setter will panic if we attempt to set an invalid value
       
   119 */
       
   120 void THCTLBcspFlags::SetSequence(TUint8 aSeq)
       
   121 	{
       
   122 	__ASSERT_DEBUG((aSeq < KMaxWindowSize), PANIC(KBcspPanicCat, EBcspInvalidSequenceValue));
       
   123 	iFlagsField &= ~KBcspSeqMask;
       
   124 	iFlagsField |= aSeq;
       
   125 	}
       
   126 
       
   127 /**
       
   128 	Trivial setter
       
   129 */
       
   130 void THCTLBcspFlags::SetCrcEnabled(TBool aCrcEnabled)
       
   131 	{
       
   132 	if(aCrcEnabled)
       
   133 		{
       
   134 		iFlagsField |= KBcspCrcPresentMask;
       
   135 		}
       
   136 	else
       
   137 		{
       
   138 		iFlagsField &= ~KBcspCrcPresentMask;
       
   139 		}
       
   140 	}
       
   141 
       
   142 void THCTLBcspFlags::SetIsReliableProtcolType(TBool aIsReliableProtcolType)
       
   143 	{
       
   144 	if(aIsReliableProtcolType)
       
   145 		{
       
   146 		iFlagsField |= KBcspProtocolTypeMask;
       
   147 		}
       
   148 	else
       
   149 		{
       
   150 		iFlagsField &= ~KBcspProtocolTypeMask;
       
   151 		}
       
   152 	}
       
   153 
       
   154 void THCTLBcspFlags::SetFlagsField(TUint8 aFlagsField)
       
   155 	{
       
   156 	iFlagsField = aFlagsField;
       
   157 	}
       
   158 	
       
   159 /**
       
   160 Implementation of Class CHCTLBcspFrame
       
   161 */
       
   162 CHCTLBcspFrame::CHCTLBcspFrame()
       
   163 	{
       
   164 	}
       
   165 
       
   166 /**
       
   167 	Method to set the flags in the Header byte of a BCSP frame
       
   168 */
       
   169 void CHCTLBcspFrame::SetFlags(TUint8 aAck, TBool aIsCrcEnabled, TBool aIsReliableProtcolType)
       
   170 	{
       
   171 	LOG_FUNC
       
   172 	iFlagHeaderByte.SetAck(aAck);
       
   173 	iFlagHeaderByte.SetCrcEnabled(aIsCrcEnabled);
       
   174 	iFlagHeaderByte.SetIsReliableProtcolType(aIsReliableProtcolType);
       
   175 	}
       
   176 
       
   177 void CHCTLBcspFrame::SetSequence(TUint8 aSeq)
       
   178 	{
       
   179 	iFlagHeaderByte.SetSequence(aSeq);
       
   180 	}
       
   181 
       
   182 TInt CHCTLBcspFrame::SetProtocolId(TUint8 aProtocolId)
       
   183 	{
       
   184 	return iProtocolId.SetProtocolId(aProtocolId);
       
   185 	}
       
   186 
       
   187 TBool CHCTLBcspFrame::CrcEnabled() const
       
   188 	{
       
   189 	return iFlagHeaderByte.CrcEnabled();
       
   190 	}
       
   191 
       
   192 TUint8 CHCTLBcspFrame::CheckSum() const
       
   193 	{
       
   194 	return iCheckSum;
       
   195 	}
       
   196 
       
   197 TUint8 CHCTLBcspFrame::ProtocolId() const
       
   198 	{
       
   199 	return iProtocolId.ProtocolId();
       
   200 	}
       
   201 
       
   202 TUint8 CHCTLBcspFrame::FlagsField() const
       
   203 	{
       
   204 	return iFlagHeaderByte.FlagsField();
       
   205 	}
       
   206 
       
   207 TUint16 CHCTLBcspFrame::PayloadLength() const
       
   208 	{
       
   209 	return static_cast<TUint16>(iPayloadPtr.Size());
       
   210 	}
       
   211 
       
   212 TInt CHCTLBcspFrame::ValidateChecksum(const TDesC8& aHeader)
       
   213 /**
       
   214 	Method to validate the checksum of a received frame header
       
   215 */
       
   216 	{
       
   217 	LOG_FUNC
       
   218 	TInt rerr = KErrNone;
       
   219 
       
   220 	if (aHeader.Length() < KBcspHeaderBytes)
       
   221 		{
       
   222 		rerr = KErrBcspHeaderCorrupt;
       
   223 		}
       
   224 	else if(aHeader[KBcspHeaderChecksumByteIndex] != CalcCheckSum(aHeader))
       
   225 		{
       
   226 		rerr = KErrBcspHeaderCorrupt;
       
   227 		}
       
   228 
       
   229 	return rerr;
       
   230 	}
       
   231 
       
   232 TDesC8& CHCTLBcspFrame::Payload()
       
   233 /**
       
   234 	Trivial getter method
       
   235 */
       
   236 	{
       
   237 	return iPayloadPtr;
       
   238 	}
       
   239 
       
   240 TUint8 CHCTLBcspFrame::Sequence() const
       
   241 /**
       
   242 	Trivial getter method
       
   243 */
       
   244 	{
       
   245 	return iFlagHeaderByte.Sequence();
       
   246 	}
       
   247 
       
   248 TUint8 CHCTLBcspFrame::Ack() const
       
   249 /**
       
   250 	Trivial getter method
       
   251 */
       
   252 	{
       
   253 	return iFlagHeaderByte.Ack();
       
   254 	}
       
   255 
       
   256 TBool CHCTLBcspFrame::IsReliableProtcolType() const
       
   257 /**
       
   258 	Trivial getter method
       
   259 */
       
   260 	{
       
   261 	return iFlagHeaderByte.IsReliableProtcolType();
       
   262 	}
       
   263 
       
   264 TUint16 CHCTLBcspFrame::CalcCRC(const TDesC8& aData)
       
   265 /**
       
   266  	@param aData - Parameters Buffer upon which to calculate crc
       
   267  	@return CRC Value TUint16
       
   268 */
       
   269  	{
       
   270  	LOG_FUNC
       
   271   	TUint16 crcValue = 0xffff;	// Fill the shift register with 1s
       
   272   	TUint8 dataByte;
       
   273   	
       
   274   	for (TInt i=0;i<aData.Length();i++)
       
   275   		{
       
   276   		dataByte = aData[i];
       
   277   		crcValue = static_cast<TUint16>((crcValue >> 4) ^ KCrcTable[(crcValue^dataByte) & 0xf]);
       
   278   		crcValue = static_cast<TUint16>((crcValue >> 4) ^ KCrcTable[(crcValue^(dataByte >> 4)) & 0xf]);
       
   279   		}
       
   280   	return ReverseCrcBits(crcValue); // Reverse all the bits in the CRC
       
   281   	}
       
   282 
       
   283 TUint16 CHCTLBcspFrame::ReverseCrcBits(TUint16 aCRCValue)
       
   284 /**
       
   285 	Method to reverse the CRC Value
       
   286 	@param aCRCValue
       
   287 */
       
   288 	{
       
   289 	TUint16 result = 0; 
       
   290 	for(TInt b=0;b<16;b++)
       
   291 		{
       
   292 		result = static_cast<TUint16>(result << 1) ;
       
   293 		result |= (aCRCValue & 1);
       
   294 		aCRCValue = static_cast<TUint16>(aCRCValue >> 1);
       
   295 		}
       
   296 	return result;
       
   297 	}
       
   298 
       
   299 
       
   300 
       
   301 TUint8 CHCTLBcspFrame::CalcCheckSum(const TDesC8& aHeader)
       
   302 /**
       
   303 	Method to calculate the checksum
       
   304 	The Checksum error is used to check the integrity of the header:
       
   305 */
       
   306 	{
       
   307 	LOG_FUNC
       
   308 	__ASSERT_DEBUG(aHeader.Length() >= KBcspHeaderBytes, PANIC(KBcspPanicCat, EBadBcspFrame));
       
   309 	TUint8 tempsum = static_cast <TUint8>(aHeader[KBcspHeaderFlagsByteIndex] + 
       
   310 	                                      aHeader[KBcspHeaderByte2Index] + 
       
   311 	                                      aHeader[KBcspHeaderByte3Index]);
       
   312 	return ~tempsum;
       
   313 	}
       
   314 
       
   315 void CHCTLBcspFrame::Reset()
       
   316 /**
       
   317 	Method to reset the frame
       
   318 */
       
   319 	{
       
   320 	LOG_FUNC
       
   321 	iIsValid = EFalse;
       
   322 	}
       
   323 
       
   324 TBool CHCTLBcspFrame::IsValid() const
       
   325 /**
       
   326 	Trvial getter method
       
   327 */
       
   328  	{
       
   329  	return iIsValid;
       
   330  	}
       
   331 
       
   332 
       
   333 /**
       
   334 Implementation of Class CTxHctlBcspFrame
       
   335 */
       
   336 
       
   337 CTxHctlBcspFrame* CTxHctlBcspFrame::NewLC(const TDesC8& aHCIPayload)
       
   338 	{
       
   339 	LOG_STATIC_FUNC
       
   340 	CTxHctlBcspFrame* self= new(ELeave) CTxHctlBcspFrame();
       
   341 	CleanupStack::PushL(self);
       
   342 	self->ConstructL(aHCIPayload);
       
   343 	return self;
       
   344 	}
       
   345 
       
   346 CTxHctlBcspFrame* CTxHctlBcspFrame::NewLC(TInt aFrameSize)
       
   347 	{
       
   348 	LOG_STATIC_FUNC
       
   349 	CTxHctlBcspFrame* self= new(ELeave) CTxHctlBcspFrame();
       
   350 	CleanupStack::PushL(self);
       
   351 	self->ConstructL(aFrameSize);
       
   352 	return self;
       
   353 	}
       
   354 
       
   355 CTxHctlBcspFrame* CTxHctlBcspFrame::NewL(const TDesC8& aHCIPayload)
       
   356 	{
       
   357 	LOG_STATIC_FUNC
       
   358 	CTxHctlBcspFrame *self=NewLC(aHCIPayload);
       
   359 	CleanupStack::Pop(self);
       
   360 	return self;
       
   361 	}
       
   362 
       
   363 CTxHctlBcspFrame* CTxHctlBcspFrame::NewL(TInt aFrameSize)
       
   364 	{
       
   365 	LOG_STATIC_FUNC
       
   366 	CTxHctlBcspFrame *self=NewLC(aFrameSize);
       
   367 	CleanupStack::Pop(self);
       
   368 	return self;
       
   369 	}
       
   370 
       
   371 void CTxHctlBcspFrame::ConstructL(const TDesC8& aHCIPayload)
       
   372 	{
       
   373 	LOG_FUNC
       
   374 
       
   375 	// Instantiates iFrame and the TPtr8 iFramePtr to it
       
   376 	// Then calls the SetPayload() method with the param aHCIPayload
       
   377 	iFrame = HBufC8::NewL(aHCIPayload.Length() + KBcspHeaderBytes + KBcspCrcBytes);
       
   378 	iFramePtr.Set(iFrame->Des());
       
   379 
       
   380 	SetPayload(aHCIPayload);
       
   381 	}
       
   382 
       
   383 void CTxHctlBcspFrame::ConstructL(TInt aFrameSize)
       
   384 	{
       
   385 	LOG_FUNC
       
   386 
       
   387 	// Instantiates iFrame and the TPtr8 iFramePtr to it
       
   388 	// then calls the SetPayload() method.
       
   389 	iFrame = HBufC8::NewL(KBcspHeaderBytes + KBcspCrcBytes + aFrameSize);
       
   390 	iFramePtr.Set(iFrame->Des());
       
   391 
       
   392 	SetPayload();
       
   393 	}
       
   394 
       
   395 void CTxHctlBcspFrame::SetPayload(const TDesC8 &aPayload)
       
   396 	{
       
   397 	iFramePtr.SetMax();
       
   398 	TPtr8 payload(iFramePtr.MidTPtr(KBcspHeaderBytes));
       
   399 
       
   400 	payload = aPayload.Right(payload.MaxSize());
       
   401 	iPayloadPtr.Set(payload);
       
   402 
       
   403 	iFramePtr.SetLength(KBcspHeaderBytes + aPayload.Size());
       
   404 
       
   405 	iIsValid = ETrue;
       
   406 	}
       
   407 
       
   408 void CTxHctlBcspFrame::SetPayload()
       
   409 	{
       
   410 	LOG_FUNC
       
   411 	iPayloadPtr.Set(KNullDesC8);
       
   412 
       
   413 	iFramePtr.SetLength(KBcspHeaderBytes);
       
   414 
       
   415 	iIsValid = ETrue;
       
   416 	}
       
   417 
       
   418 CTxHctlBcspFrame::CTxHctlBcspFrame()
       
   419   : iFramePtr(NULL, 0, 0)
       
   420 	{
       
   421 	LOG_FUNC
       
   422 	}
       
   423 
       
   424 CTxHctlBcspFrame::~CTxHctlBcspFrame()
       
   425 	{
       
   426 	LOG_FUNC
       
   427 	delete iFrame;
       
   428 	}
       
   429 
       
   430 void CTxHctlBcspFrame::BuildFrame()
       
   431 /**
       
   432 	Build  BCSP frame method
       
   433 
       
   434 	Zero the frame Ptr
       
   435 	Set the frame length to KMaxHeaderBytes - to address the BCSP header bytes
       
   436 
       
   437 	Populate all 4 header bytes with the Flag byte,PayloadLength, ProtocolId and checksum
       
   438 
       
   439 	Set the frame length to Payloadlength + KMaxBcspHeaderBytes
       
   440 
       
   441 	Populate the BCSP frame payload
       
   442 
       
   443 	Check if the CRC flag is set if it is then Calculate the CRC of the Whole Frame and append the crc
       
   444 
       
   445 */
       
   446 	{
       
   447 	LOG_FUNC
       
   448 	iFramePtr.SetLength(KBcspHeaderBytes);
       
   449 	iFramePtr[KBcspHeaderFlagsByteIndex] = iFlagHeaderByte.FlagsField();
       
   450 	iFramePtr[KBcspHeaderByte2Index] = static_cast<TUint8>(ProtocolId() | ((PayloadLength() & 0xf) << 4));
       
   451 	iFramePtr[KBcspHeaderByte3Index] = static_cast<TUint8>((PayloadLength() & 0xff0) >> 4);
       
   452 	iFramePtr[KBcspHeaderChecksumByteIndex] = CalcCheckSum(iFramePtr);
       
   453 
       
   454 	iFramePtr.SetLength(PayloadLength() + KBcspHeaderBytes);
       
   455 
       
   456 	if (PayloadLength() > 0)
       
   457 		{
       
   458 		iPayloadPtr.Set(iFramePtr.Ptr() + KBcspHeaderBytes, PayloadLength());
       
   459 		}
       
   460 
       
   461 	if (CrcEnabled())
       
   462 		{
       
   463 		TUint16 crcValue = CalcCRC(iFramePtr.Left(PayloadLength() + KBcspHeaderBytes));
       
   464 		iFramePtr.Append((crcValue & 0xff00) >> 8); //Append first byte of CRC
       
   465 		iFramePtr.Append(crcValue & 0x00ff);        //Append second Byte of CRC
       
   466 		}
       
   467 	}
       
   468 
       
   469 void CTxHctlBcspFrame::Reset()
       
   470 /**
       
   471 	Reset the BCSP frame and set retries to 0
       
   472 */
       
   473 	{
       
   474 	LOG_FUNC
       
   475 	CHCTLBcspFrame::Reset();
       
   476 	iRetries = 0;
       
   477 	}
       
   478 
       
   479 void CTxHctlBcspFrame::SlipEncodeFrame(TPtr8 aSlipFrame)
       
   480 /**
       
   481 	SlipEncoding method
       
   482 	SLIP is outlined in RFC 1055. The principle is to surround each packet
       
   483 	with a start and an end special byte. This allows the beginning and the end of a packet to be
       
   484 	found and consequently the length of the packet to be known.
       
   485 	The packet encoding and decoding scheme has two basic rules:
       
   486 	Because the special byte can only appear in the stream as a delimiter, it has to be replaced inside
       
   487 	the payload by an escape sequence, composed of two bytes: 0xc0 is mapped to 0xDB 0xDC.
       
   488 	Consequently 0xDB is also a special byte, and each occurrence of this escape byte is replaced
       
   489 	by an another sequence of two bytes: 0xDB 0xDD
       
   490 	This method is very quick and simple for encoding a packet. The corresponding Decoding
       
   491 	procedure is used for received packets.
       
   492 	Moreover, as explained in the section regarding detecting errors, the SLIP layer provides a
       
   493 	method of error detection.
       
   494 */
       
   495 	{
       
   496 	LOG_FUNC
       
   497 	__ASSERT_DEBUG(iFrame != NULL, PANIC(KBcspPanicCat, EBadFramePointer));
       
   498 
       
   499 	aSlipFrame.Zero();
       
   500 	aSlipFrame.SetMax();
       
   501 
       
   502 	TInt i=0;
       
   503 	TInt j=0;
       
   504 
       
   505 	aSlipFrame[j++] = KSlipWrapperByte;
       
   506 
       
   507 	for (i=0;i<iFrame->Length();i++)
       
   508 		{
       
   509 		switch((*iFrame)[i])
       
   510 			{
       
   511 			case KSlipWrapperByte:
       
   512 				{
       
   513 				aSlipFrame[j++] = KSlipByteDB;
       
   514 				aSlipFrame[j++] = KSlipByteDC;
       
   515 				break;
       
   516 				}
       
   517 			case 0xdb:
       
   518 				{
       
   519 				aSlipFrame[j++] = KSlipByteDB;
       
   520 				aSlipFrame[j++] = KSlipByteDD;
       
   521 				break;
       
   522 				}
       
   523 
       
   524 			default:
       
   525 				{
       
   526 				aSlipFrame[j++] = (*iFrame)[i];
       
   527 				break;
       
   528 				}
       
   529 			}
       
   530 		}
       
   531 
       
   532 	aSlipFrame[j++] = KSlipWrapperByte;
       
   533 	aSlipFrame.SetLength(j);
       
   534 	}
       
   535 
       
   536 
       
   537 
       
   538 /**
       
   539 Implementation of Class CRxHctlBcspFrame
       
   540 */
       
   541 
       
   542 
       
   543 CRxHctlBcspFrame* CRxHctlBcspFrame::NewL()
       
   544 /**
       
   545 	CRxHctlBcspFrame::NewL() method
       
   546 	
       
   547 	@return self
       
   548 */
       
   549 	{
       
   550 	LOG_STATIC_FUNC
       
   551 	return new(ELeave) CRxHctlBcspFrame;
       
   552 	}
       
   553 
       
   554 TInt CRxHctlBcspFrame::SlipDecodeFrame(const TDesC8& aReceivedFrame)
       
   555 /**
       
   556 	Slip decoding methopd for received frames
       
   557 */
       
   558 	{
       
   559 	LOG_FUNC
       
   560 	TInt rerr = KErrNone;
       
   561 
       
   562  	// TPtrC8 packet = aReceivedFrame;
       
   563 	TPtr8 packet(const_cast<TUint8*>(aReceivedFrame.Ptr()),
       
   564 			     aReceivedFrame.Size(),
       
   565 				 aReceivedFrame.Size());
       
   566 
       
   567 	if ((packet.Length() < KBcspHeaderBytes) || (packet[packet.Length()-1] != KSlipWrapperByte) || (packet[0] == KSlipWrapperByte))
       
   568 		{
       
   569 		/** 
       
   570 		Fail slip decoding for one of or none of these reasons:
       
   571 			1. first byte is another slip wrapper byte (One has been received already and discarded in terminating reads)
       
   572 			   should not receive 2 consecutive slip wrapper byte in any one slip packet
       
   573 			2. The final packet byte is not a slip wrapper byte
       
   574 		
       
   575 		NB. A good slip Packet at this stage should have x-bytes appended with one slip wrapper byte.
       
   576 		This is because the first slip wrapper byte was already picked up on the first terminated read.
       
   577 		*/
       
   578 		rerr = KErrSlipCorrupted;
       
   579 		}
       
   580 	else
       
   581 		{
       
   582 		packet.SetLength(packet.Length() - 1); // Remove the last 0xc0 byte.
       
   583 
       
   584 		TInt  i = 0;
       
   585 		TInt  offset = 0;
       
   586 		TInt  length = packet.Length();
       
   587 
       
   588 		while ( (i<length) && (rerr == KErrNone) )
       
   589 			{
       
   590 			switch (packet[i])
       
   591 				{
       
   592 				case 0xc0:	// If this appears do nothing as it should be either the header or trailer byte checked above
       
   593 					rerr = KErrSlipCorrupted;
       
   594 					break;
       
   595 
       
   596 				case 0xdb:
       
   597 					i++; // Check the next byte immediately
       
   598 					offset--;
       
   599 					if ( i<length )
       
   600 						{
       
   601 						switch (packet[i])
       
   602 							{
       
   603 							case 0xdc:
       
   604 								packet[i+offset] = 0xc0;
       
   605 								break;
       
   606 
       
   607 							case 0xdd:
       
   608 								packet[i+offset] = 0xdb;
       
   609 								break;
       
   610 
       
   611 							default:
       
   612 								rerr = KErrSlipCorrupted;
       
   613 							};
       
   614 						}
       
   615 					else
       
   616 						{
       
   617 						rerr = KErrSlipCorrupted;
       
   618 						}
       
   619 					break;
       
   620 
       
   621 				default:
       
   622 					if ( offset )
       
   623 						{
       
   624 						packet[i+offset] = packet[i];
       
   625 						}
       
   626 					break;
       
   627 				}
       
   628 			i++;
       
   629 			}
       
   630 
       
   631 		if(rerr == KErrNone)
       
   632 			{
       
   633 			packet.SetLength(length + offset);
       
   634 			rerr = Set(packet);
       
   635 			}
       
   636 		}
       
   637 
       
   638 	return rerr;
       
   639 	}
       
   640 
       
   641 TInt CRxHctlBcspFrame::Set(const TDesC8& aFrame)
       
   642 /**
       
   643 	Populate a BCSP frame object and vaildate its contents via the various BCSP error 
       
   644 	checking methods
       
   645 */
       
   646 	{
       
   647 	LOG_FUNC
       
   648 	TInt err = ValidateChecksum(aFrame);	// Do Checksum check
       
   649 	TInt errId = KErrNone;
       
   650 	TUint16 payloadLen = 0;
       
   651 
       
   652 	if (err == KErrNone)
       
   653 		{
       
   654 		ParseFlagByte(aFrame);	// populate THctlBcspFlags members
       
   655 		
       
   656 		errId = ParsePayloadLenProtId(aFrame, payloadLen);	
       
   657 		if (errId)
       
   658 			{
       
   659 			return errId;	// corrupted Id, no point in continuing 	
       
   660 			}
       
   661 
       
   662 		// Check header payload length field is the same as the actual HCIPayloadLength
       
   663 		if (CrcEnabled())
       
   664 			{
       
   665 			TInt actualPayloadLen = aFrame.Length() - KBcspCrcBytes - KBcspHeaderBytes;
       
   666 			if(actualPayloadLen >= 0) // Check payload is sufficient length
       
   667 				{
       
   668 				iPayloadPtr.Set(aFrame.Ptr() + KBcspHeaderBytes, actualPayloadLen);
       
   669 
       
   670 				if (PayloadLength() != payloadLen) // Check payload length
       
   671 					{
       
   672 					LOG(_L8("CRxHctlBcspFrame: KErrBcspCorruptedHCIPayload..."));
       
   673 					err = KErrBcspCorruptedHCIPayload;
       
   674 					}
       
   675 				else if (CheckCRC(aFrame) != KErrNone) // Do CRC Check
       
   676 					{
       
   677 					LOG(_L8("CRxHctlBcspFrame: KErrBCSPCRCCheckFailed..."));
       
   678 					err = KErrBcspCRCCheckFailed;
       
   679 					}
       
   680 				}
       
   681 			else
       
   682 				{
       
   683 				LOG(_L8("CRxHctlBcspFrame: KErrBcspCorruptedHCIPayload..."));
       
   684 				err = KErrBcspCorruptedHCIPayload;
       
   685 				}
       
   686 			}
       
   687 		else 
       
   688 			{
       
   689 			TInt actualPayloadLen = aFrame.Length() - KBcspHeaderBytes;
       
   690 			// There is no need to check that the payload is of sufficient length since
       
   691 			// the ValidateChecksum call would have failed and stopped us getting here.
       
   692 			__ASSERT_DEBUG(actualPayloadLen >= 0, PANIC(KBcspPanicCat, EBadBcspFrame));
       
   693 			iPayloadPtr.Set(aFrame.Ptr() + KBcspHeaderBytes, actualPayloadLen);
       
   694 			if (PayloadLength() != payloadLen) 
       
   695 				{
       
   696 				LOG(_L8("HCTLBcsp: KErrBcspCorruptedHCIPayload..."));
       
   697 				LOGHEXDESC(aFrame);
       
   698 				err = KErrBcspCorruptedHCIPayload;
       
   699 				}
       
   700 			}
       
   701 		}
       
   702 
       
   703 	iIsValid = (err == KErrNone) ? ETrue : EFalse;
       
   704 
       
   705 	return err;
       
   706 	}
       
   707 
       
   708 
       
   709 CRxHctlBcspFrame::CRxHctlBcspFrame()
       
   710   : CHCTLBcspFrame()
       
   711 	{
       
   712 	}
       
   713 
       
   714 void CRxHctlBcspFrame::ParseFlagByte(const TDesC8& aHeader)
       
   715 	{
       
   716 	LOG_FUNC
       
   717 	LOG1(_L8("Parse HeaderByte %02x"), aHeader[KBcspHeaderFlagsByteIndex]);
       
   718 
       
   719 	iFlagHeaderByte.SetFlagsField(aHeader[KBcspHeaderFlagsByteIndex]);
       
   720 	}
       
   721 
       
   722 TInt CRxHctlBcspFrame::ParsePayloadLenProtId(const TDesC8& aHeader, TUint16& aRetPayloadLen)
       
   723 /**
       
   724 	Method to extract the Payload Length and Protocol Id from the 2nd and 3rd header bytes
       
   725 */
       
   726 	{
       
   727 	LOG_FUNC
       
   728 	TInt err = KErrNone;
       
   729 
       
   730 	err = SetProtocolId((aHeader[KBcspHeaderByte2Index] & KBcspProtocolIdMask));
       
   731 	if (!err)
       
   732 		{
       
   733 		aRetPayloadLen = static_cast<TUint16>(((aHeader[KBcspHeaderByte2Index] & KBcspPayloadLen1stBitsMask) >> 4) | (aHeader[KBcspHeaderByte3Index] << 4));
       
   734 		}
       
   735 	
       
   736 	return err;
       
   737 	}
       
   738 
       
   739 TInt CRxHctlBcspFrame::CheckCRC(const TDesC8 &aFrame)
       
   740 /**
       
   741 	Method to check and validate the CRC
       
   742 */
       
   743 	{
       
   744 	LOG_FUNC
       
   745 	TPtrC8 frame(aFrame.Ptr(), aFrame.Size() - KBcspCrcBytes);
       
   746 
       
   747 	TUint16 tempCRCvalue;
       
   748 	TUint16 crcValue = CalcCRC(frame);	// Calculates and sets iCRCValue
       
   749 
       
   750 	//compare with hctl trailer CRC value
       
   751 	TBuf8<2> crcval;
       
   752 	crcval = aFrame.Right(KBcspCrcBytes);
       
   753 	
       
   754 	tempCRCvalue = static_cast<TUint16>((crcval[0] << 8) + crcval[1]);
       
   755 
       
   756 	return ((crcValue == tempCRCvalue) ? KErrNone : KErrBcspCRCCheckFailed);
       
   757 	}