bthci/hci2implementations/hctls/bcsp/src/hctlbcspFrameQueue.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 "hctlbcspFrameQueue.h"
       
    22 
       
    23 #include "hctlbcsp.h"
       
    24 #include "hctlbcspconsts.h"
       
    25 #include "hctlbcspsequencer.h"
       
    26 #include "bcsputils.h"
       
    27 #include "debug.h"
       
    28 #include "hctlbcspframe.h"
       
    29 
       
    30 CHCTLBcspWindow::CHCTLBcspWindow(TInt aWindowSize, TInt aNumberOfSeqIds)
       
    31   : iEndOfWindow(aWindowSize - 1),
       
    32     iWindowSize(aWindowSize),
       
    33     iNumberOfSeqIds(aNumberOfSeqIds),
       
    34 	iFrameQue(_FOFF(CTxHctlBcspFrame,iLink))
       
    35 	{
       
    36 	LOG_FUNC
       
    37 	}
       
    38 
       
    39 CHCTLBcspWindow* CHCTLBcspWindow::NewL(TInt aWindowSize, TInt aFrameSize, TInt aNumberOfSeqIds)
       
    40 	{
       
    41 	LOG_STATIC_FUNC
       
    42 
       
    43 	CHCTLBcspWindow *self = new (ELeave) CHCTLBcspWindow(aWindowSize, aNumberOfSeqIds);
       
    44 	CleanupStack::PushL(self);
       
    45 	self->ConstructL(aFrameSize);
       
    46 	CleanupStack::Pop(self);
       
    47 	return self;
       
    48 	}
       
    49 
       
    50 void CHCTLBcspWindow::ConstructL(TInt aFrameSize)
       
    51 	{
       
    52 	LOG_FUNC
       
    53 
       
    54 	for(TInt i=0;i<iWindowSize;i++)
       
    55 		{
       
    56 		CTxHctlBcspFrame *frame = CTxHctlBcspFrame::NewL(aFrameSize);
       
    57 		frame->Reset();
       
    58 		iFrameQue.AddLast(*frame);
       
    59 
       
    60 #ifdef _DEBUG_WINDOW
       
    61 		LOG1(_L8("frame added 0x%08x"),frame);
       
    62 #endif
       
    63 		}
       
    64 #ifdef _DEBUG_WINDOW
       
    65 	TraceWindowVars();
       
    66 	TraceQueue();
       
    67 #endif
       
    68 	}
       
    69 
       
    70 CHCTLBcspWindow::~CHCTLBcspWindow()
       
    71 	{
       
    72 	LOG_FUNC
       
    73 
       
    74 	for (TInt i=0;i<iWindowSize;i++)
       
    75 		{
       
    76 		CTxHctlBcspFrame* frame = iFrameQue.First();
       
    77 		iFrameQue.Remove(*frame);
       
    78 		delete frame;
       
    79 		}
       
    80 	}
       
    81 
       
    82 TInt CHCTLBcspWindow::StartOfWindow() const
       
    83 	{
       
    84 	LOG_FUNC
       
    85 	 
       
    86 	return iStartOfWindow; 
       
    87 	}
       
    88 	
       
    89 TInt CHCTLBcspWindow::ToSeqId(TInt aIndex) const
       
    90 	{ 
       
    91 	LOG_FUNC
       
    92 
       
    93 	return (aIndex + iStartOfWindow)%iNumberOfSeqIds; 
       
    94 	}
       
    95 	
       
    96 TInt CHCTLBcspWindow::ToWindowIndex(TInt aSeqId) const 
       
    97 	{
       
    98 	LOG_FUNC
       
    99 	
       
   100 	TInt index = aSeqId - iStartOfWindow;
       
   101 	if ( index < 0 )
       
   102 		{
       
   103 		index += iNumberOfSeqIds;
       
   104 		}
       
   105 	return index; 
       
   106 	}
       
   107 	
       
   108 void CHCTLBcspWindow::IncrementSeqId(TInt &aSeqId) const
       
   109 	{ 
       
   110 	aSeqId++; 
       
   111 	aSeqId %= iNumberOfSeqIds;
       
   112 	}
       
   113 
       
   114 
       
   115 CTxHctlBcspFrame* CHCTLBcspWindow::GetFrame(TInt aIndex)
       
   116 /**
       
   117 	Method to retrieve a frame for transmission
       
   118 */
       
   119 	{
       
   120 	LOG_FUNC
       
   121 
       
   122 	__TEST_INVARIANT;
       
   123 
       
   124 	TInt index = ToWindowIndex(aIndex);
       
   125 	__ASSERT_DEBUG((index>=0) && (index<iWindowSize), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   126 
       
   127 	TSglQueIter<CTxHctlBcspFrame> iter(iFrameQue);
       
   128 	CTxHctlBcspFrame* frame = iter++;
       
   129 
       
   130 	while ( index > 0 )
       
   131 		{
       
   132 		frame = iter++;
       
   133 		index--;
       
   134 		}
       
   135 
       
   136 #ifdef _DEBUG_WINDOW
       
   137 	LOG2(_L8("frame got 0x%08x (index:%d)"), frame, aIndex);
       
   138 #endif
       
   139 
       
   140 	return frame;
       
   141 	}
       
   142 
       
   143 TInt CHCTLBcspWindow::FreeFrames()
       
   144 /**
       
   145 	Method to free up space in transmit queue for sending more BCSP frames
       
   146 */
       
   147 	{
       
   148 	LOG_FUNC
       
   149 
       
   150 	__TEST_INVARIANT;
       
   151 
       
   152 	return ToWindowIndex(iEndOfWindow) - ToWindowIndex(iWritePosition);
       
   153 	}
       
   154 
       
   155 CTxHctlBcspFrame *CHCTLBcspWindow::WriteFrame()
       
   156 /**
       
   157 	Method to Write a frame to the frame queue
       
   158 */	
       
   159 	{
       
   160 	LOG_FUNC
       
   161 
       
   162 	CTxHctlBcspFrame *frame = NULL;
       
   163 
       
   164 	__TEST_INVARIANT;
       
   165 
       
   166 	if ( iWritePosition != iEndOfWindow )
       
   167 		{
       
   168 		frame = GetFrame(iWritePosition);
       
   169 		
       
   170 		if(frame)
       
   171 			{
       
   172 			IncrementSeqId(iWritePosition);
       
   173 			// Make sure we're not returning a valid frame to be overwritten
       
   174 			__ASSERT_DEBUG(!frame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   175 			}
       
   176 		else
       
   177 			{
       
   178 	#ifdef _DEBUG_WINDOW
       
   179 	FTRACE(FPrintBCSP(_L("Bcsp frame queue blocked (panic now deprecated)")));
       
   180 	#endif
       
   181 			}
       
   182 
       
   183 #ifdef _DEBUG_WINDOW
       
   184 		LOG(_L8("Post Write"));
       
   185 		TraceWindowVars();
       
   186 		TraceQueue();
       
   187 #endif
       
   188 		}
       
   189 
       
   190 	__TEST_INVARIANT;
       
   191 
       
   192 	return frame;
       
   193 	}
       
   194 
       
   195 CTxHctlBcspFrame *CHCTLBcspWindow::ReadFrame()
       
   196 /**
       
   197 	Method to read a frame from the Transmit Queue
       
   198 
       
   199 	@return CTxHctlBcspFrame * frame
       
   200 */	
       
   201 	{
       
   202 	LOG_FUNC
       
   203 
       
   204 	CTxHctlBcspFrame *frame = NULL;
       
   205 
       
   206 	__TEST_INVARIANT;
       
   207 
       
   208 	if ( iReadPosition != iWritePosition )
       
   209 		{
       
   210 		frame = GetFrame(iReadPosition);
       
   211 		frame->SetSequence(static_cast<TUint8>(iReadPosition));
       
   212 
       
   213 		if (iReadPosition == iHighReadPosition)
       
   214 			{
       
   215 			IncrementSeqId(iHighReadPosition);
       
   216 			}
       
   217 		IncrementSeqId(iReadPosition);
       
   218 
       
   219 #ifdef _DEBUG_WINDOW
       
   220 		LOG(_L8("Post Read"));
       
   221 		TraceWindowVars();
       
   222 		TraceQueue();
       
   223 #endif
       
   224 		// Make sure we're returning a valid frame to be used
       
   225 		__ASSERT_DEBUG(frame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   226 		}
       
   227 
       
   228 	__TEST_INVARIANT;
       
   229 
       
   230 	return frame;
       
   231 }
       
   232 
       
   233 TBool CHCTLBcspWindow::Acknowledged(TInt aAckNo)
       
   234 /**
       
   235 	Method to handle TxFrame acknowledgement
       
   236 	Remove the frame that is acknowledged
       
   237 	@param current Rx Ack value, KErrTimedOut if ack timed out
       
   238 */
       
   239 	{
       
   240 	LOG_FUNC
       
   241 
       
   242 	TBool framesRemainingInWindow = EFalse;
       
   243 
       
   244 #ifdef _DEBUG_WINDOW
       
   245 	LOG(_L8("Pre Ack"));
       
   246 	TraceWindowVars();
       
   247 #endif
       
   248 
       
   249 	__TEST_INVARIANT;
       
   250 
       
   251 	const TBool resetWindow = ((aAckNo >= 0) && (ToWindowIndex(aAckNo) > ToWindowIndex(iHighReadPosition))) ? ETrue : EFalse;
       
   252 
       
   253 	if (resetWindow)
       
   254 		{
       
   255 #ifdef _DEBUG_WINDOW
       
   256 		LOG1(_L8("Ack for unsent packet (%d), resetting entire window!!!"), aAckNo);
       
   257 #endif
       
   258 		// reset frames
       
   259 		TSglQueIter<CTxHctlBcspFrame> iter(iFrameQue);
       
   260 		CTxHctlBcspFrame *frame = iter++;
       
   261 
       
   262 		while (iter)
       
   263 			{
       
   264 			frame->Reset();
       
   265 			frame = iter++;
       
   266 			}
       
   267 
       
   268 		//reset window variables
       
   269 		iStartOfWindow = aAckNo;
       
   270 		iStartOfWindow %= iNumberOfSeqIds;
       
   271 
       
   272 		iEndOfWindow  = iStartOfWindow + iWindowSize-1;
       
   273 		iEndOfWindow %= iNumberOfSeqIds;
       
   274 
       
   275 		iWritePosition = iHighReadPosition = iReadPosition = iStartOfWindow;
       
   276 
       
   277 		framesRemainingInWindow = ETrue;
       
   278 		}
       
   279 	else if (iReadPosition != iStartOfWindow) // frames waiting to be acknowledged
       
   280 		{
       
   281 		LOG1(_L("Ack(%d)"), aAckNo);
       
   282 
       
   283 		if ( aAckNo >= 0 )
       
   284 			{
       
   285 			aAckNo %= iNumberOfSeqIds; // Make sure we wrap around at the end of the window
       
   286 			LOG1(_L8("Ack(%d)"), aAckNo);
       
   287 
       
   288 			// TInt  readIndex = ackWindowIndex;
       
   289 			TBool found = EFalse;
       
   290 			TInt i = iStartOfWindow;
       
   291 
       
   292 			while(!found && (i != iEndOfWindow))
       
   293 				{
       
   294 				if((i == aAckNo))
       
   295 					{
       
   296 					found = ETrue;
       
   297 					}
       
   298 				else if(!found)
       
   299 					{
       
   300 					// This frame is before the ackWindowIndex therefore we should reset it
       
   301 					CTxHctlBcspFrame* frame = iFrameQue.First();
       
   302 					frame->Reset();
       
   303 					iFrameQue.Remove(*frame);
       
   304 					iFrameQue.AddLast(*frame);
       
   305 					}
       
   306 				IncrementSeqId(i);
       
   307 				}
       
   308 
       
   309 			iStartOfWindow = aAckNo;
       
   310 			iStartOfWindow %= iNumberOfSeqIds;
       
   311 
       
   312 			iEndOfWindow = iStartOfWindow + iWindowSize - 1;
       
   313 			iEndOfWindow %= iNumberOfSeqIds;
       
   314 			}
       
   315 
       
   316 		// We've just had an acknowledgement so we need to resend from the start of the buffer
       
   317 		iReadPosition = iStartOfWindow;
       
   318 
       
   319 		// We've just rationalised the window. The write position can remain where it was.
       
   320 		framesRemainingInWindow = ETrue;
       
   321 		}
       
   322 
       
   323 #ifdef _DEBUG_WINDOW
       
   324 	LOG(_L("Post Ack"));
       
   325 	TraceWindowVars();
       
   326 	TraceQueue();
       
   327 #endif
       
   328 
       
   329 	__TEST_INVARIANT;
       
   330 
       
   331 	return framesRemainingInWindow;
       
   332 	}
       
   333 
       
   334 void CHCTLBcspWindow::__DbgTestInvariant(void) const
       
   335 /**
       
   336 	Debug method
       
   337 */
       
   338 	{
       
   339 	// Check that the class is internally consistent
       
   340 	__ASSERT_DEBUG(iNumberOfSeqIds>0,                                              User::Invariant());
       
   341 	__ASSERT_DEBUG((iWindowSize>0) && (iWindowSize <= iNumberOfSeqIds),            User::Invariant());
       
   342 
       
   343 	__ASSERT_DEBUG((iStartOfWindow>=0) && (iStartOfWindow<=iNumberOfSeqIds),       User::Invariant());
       
   344 	__ASSERT_DEBUG((iEndOfWindow>=0)   && (iEndOfWindow<=iNumberOfSeqIds),         User::Invariant());
       
   345 	__ASSERT_DEBUG((iReadPosition>=0 ) && (iReadPosition<=iNumberOfSeqIds),        User::Invariant());
       
   346 	__ASSERT_DEBUG((iHighReadPosition>=0 ) && (iHighReadPosition<=iNumberOfSeqIds),User::Invariant());
       
   347 	__ASSERT_DEBUG((iWritePosition>=0) && (iWritePosition<=iNumberOfSeqIds),       User::Invariant());
       
   348 
       
   349 	TInt winSize = iEndOfWindow - iStartOfWindow + 1;
       
   350 	if ( winSize < 0 )
       
   351 		{
       
   352 		winSize += iNumberOfSeqIds;
       
   353 		}
       
   354 	__ASSERT_DEBUG(winSize == iWindowSize,   User::Invariant());
       
   355 	if ( iWritePosition != iEndOfWindow )
       
   356 		{
       
   357 		__ASSERT_DEBUG(ToWindowIndex(iReadPosition) <= ToWindowIndex(iHighReadPosition),  User::Invariant());
       
   358 		__ASSERT_DEBUG(ToWindowIndex(iHighReadPosition) <= ToWindowIndex(iWritePosition), User::Invariant());
       
   359 		}
       
   360 	}
       
   361 
       
   362 #ifdef _DEBUG_WINDOW
       
   363 void CHCTLBcspWindow::TraceWindowVars() const
       
   364 /**
       
   365 	Debug method
       
   366 */
       
   367 	{
       
   368 	LOG_FUNC
       
   369 	RProcess process;
       
   370 	RThread thread;
       
   371 	TName pName = process.Name();
       
   372 	TName tName = thread.Name();
       
   373 	LOG1(_L8("Process : %S"), &pName);
       
   374 	LOG1(_L8("Thread : %S"), &tName);
       
   375 	LOG6(_L8("this : 0x%08x    SOW : %d, RP : %d, HRP: %d, WP : %d, EOW :%d"),this, iStartOfWindow, iReadPosition, iHighReadPosition, iWritePosition, iEndOfWindow);
       
   376 	}
       
   377 
       
   378 void CHCTLBcspWindow::TraceQueue()
       
   379 /**
       
   380 	Debug method
       
   381 */
       
   382 	{
       
   383 	LOG_FUNC
       
   384 	LOG1(_L8("Queue Dumping this 0x%08x"), this);
       
   385 	TSglQueIter<CTxHctlBcspFrame> iter(iFrameQue);
       
   386 	CTxHctlBcspFrame *frame = iter++;
       
   387 
       
   388 	_LIT(KSpace, " ");
       
   389 	_LIT(KWriteMarker, "W");
       
   390 	_LIT(KHighMarker, "H");
       
   391 	_LIT(KReadMarker, "R");
       
   392 
       
   393 	TInt index = 0;
       
   394 	while ( index < iWindowSize )	
       
   395 		{
       
   396 	LOG6(_L8("%S %S %S this: 0x%08x, frame : 0x%08x, %d"),
       
   397 			(index == ToWindowIndex(iWritePosition)) ? &KWriteMarker : &KSpace,
       
   398 			(index == ToWindowIndex(iHighReadPosition)) ? &KHighMarker : &KSpace,
       
   399 			(index == ToWindowIndex(iReadPosition)) ? &KReadMarker : &KSpace,
       
   400 			this,
       
   401 			frame,
       
   402 			frame->IsValid()
       
   403 			);
       
   404 		frame = iter++;
       
   405 		index++;
       
   406 		}
       
   407 	}
       
   408 #endif
       
   409 
       
   410 void CHCTLBcspWindow::Reset()
       
   411 	{
       
   412 	LOG_FUNC
       
   413 
       
   414 	for(TInt i=0;i<iWindowSize;i++)
       
   415 		{
       
   416 		CTxHctlBcspFrame* frame = iFrameQue.First();
       
   417 		frame->Reset();
       
   418 		iFrameQue.Remove(*frame);
       
   419 		iFrameQue.AddLast(*frame);
       
   420 
       
   421 #ifdef _DEBUG_WINDOW
       
   422 		LOG1(_L8("frame reset 0x%08x"),frame);
       
   423 #endif
       
   424 		}
       
   425 
       
   426 	iStartOfWindow = 0;
       
   427 	iReadPosition  = 0;
       
   428 	iHighReadPosition = 0;
       
   429 	iWritePosition = 0;
       
   430 	iEndOfWindow = iWindowSize - 1;
       
   431 
       
   432 #ifdef _DEBUG_WINDOW
       
   433 	LOG(_L8("Reset"));
       
   434 
       
   435 	TraceWindowVars();
       
   436 	TraceQueue();
       
   437 #endif
       
   438 	}
       
   439 	
       
   440 /* *********************************************************************************************
       
   441  * Frame Queue - Manages the frame queues for both Reliable and Unreliable data transfer
       
   442  * ********************************************************************************************* */
       
   443 CHCTLBcspFrameQueue* CHCTLBcspFrameQueue::NewL(CHCTLBcsp &aBcsp)
       
   444 	{
       
   445 	LOG_STATIC_FUNC
       
   446 
       
   447 	CHCTLBcspFrameQueue *self = new (ELeave) CHCTLBcspFrameQueue(aBcsp);
       
   448 	CleanupStack::PushL(self);
       
   449 	self->ConstructL();
       
   450 	CleanupStack::Pop(self);
       
   451 	return self;
       
   452 	}
       
   453 
       
   454 void CHCTLBcspFrameQueue::ConstructL()
       
   455 	{
       
   456 	LOG_FUNC
       
   457 
       
   458 	// Create the queues
       
   459 	iReliableQueue   = CHCTLBcspWindow::NewL(KBcspReliableWindowSize, 
       
   460 		                                     KMaxReliablePayloadSize,
       
   461 											 KMaxBcspWindowSize);
       
   462 
       
   463 	iUnreliableQueue = CHCTLBcspWindow::NewL(KBcspUnreliableQueueSize,
       
   464 		                                     KMaxUnreliablePayloadSize,
       
   465 											 KBcspUnreliableQueueSize+1);
       
   466 
       
   467 	// Room for Slip encoded packet is twice the size of a full BCSP Packet + 2 for the 0xC0 bytes
       
   468 	iSlipEncodedFrame = HBufC8::NewL(2 + ((KMaxReliablePayloadSize + KBcspHeaderBytes + KBcspCrcBytes) * 2));
       
   469 	}
       
   470 
       
   471 CHCTLBcspFrameQueue::CHCTLBcspFrameQueue(CHCTLBcsp& aBcsp)
       
   472   : iBcsp(aBcsp)
       
   473 	{
       
   474 	LOG_FUNC
       
   475 	}
       
   476 
       
   477 CHCTLBcspFrameQueue::~CHCTLBcspFrameQueue()
       
   478 
       
   479 	{
       
   480 	LOG_FUNC
       
   481 
       
   482 	delete iUnreliableQueue;
       
   483 	delete iReliableQueue;
       
   484 	delete iSlipEncodedFrame;
       
   485 	}
       
   486 
       
   487 
       
   488 void CHCTLBcspFrameQueue::SetSequencer(CHCTLBcspSequencer& aSequencer)
       
   489 /**
       
   490 	Simple method to initialise iSequencer with @param &aSequencer
       
   491 */
       
   492 	{
       
   493 	LOG_FUNC
       
   494 
       
   495 	iSequencer = &aSequencer;
       
   496 	}
       
   497 
       
   498 TInt CHCTLBcspFrameQueue::GetNextFrame(TDesC8* &aFrame, TBool& aIsReliable)
       
   499 /**
       
   500 	Method to get the next frame from the frame queue and then to build and slip encode it
       
   501 
       
   502 	@param &aFrame
       
   503 	@param aIsReliable a reference to a TBool which will be set to ETrue if the
       
   504 	       Frame is from the reliable queue.
       
   505 	@return err
       
   506 */
       
   507 	{
       
   508 	LOG_FUNC
       
   509 
       
   510 	TInt err = KErrNone;
       
   511 
       
   512 	CTxHctlBcspFrame *frame = iUnreliableQueue->ReadFrame();
       
   513 
       
   514 	if ( frame )
       
   515 		{
       
   516 		// Got unreliable frame
       
   517 		iUnreliableQueue->Acknowledged(iUnreliableQueue->StartOfWindow()+1); // Remove the first frame from the window
       
   518 		frame->SetSequence(0);
       
   519 		aIsReliable = EFalse;
       
   520 		}
       
   521 	else
       
   522 		{
       
   523 		// Couldn't get an unreliable frame, so ... get a reliable frame
       
   524 		frame = iReliableQueue->ReadFrame();
       
   525 
       
   526 		if ( !frame )
       
   527 			{
       
   528 			// We can't get a reliable frame either
       
   529 			err = KErrBcspNothingToSend;
       
   530 			aIsReliable = EFalse;
       
   531 			}
       
   532 		else
       
   533 			{
       
   534 			// We've got a reliable frame - increment the retry count
       
   535 			frame->IncrementRetries();
       
   536 			frame->SetFlags(iSequencer->TxAck(), ETrue, ETrue);
       
   537 			if ( frame->Retries() >= KTxRetryLimit )
       
   538 				{
       
   539 				err = KErrBcspMaxRetries;
       
   540 				}
       
   541 
       
   542 			aIsReliable = ETrue;
       
   543 			}
       
   544 		}
       
   545 
       
   546 	if ( !err )
       
   547 		{
       
   548 		// No errors so far, so SlipEncode the frame into iSlipEncodedFrame
       
   549 		frame->BuildFrame();
       
   550 		frame->SlipEncodeFrame(iSlipEncodedFrame->Des());
       
   551 		aFrame = iSlipEncodedFrame;
       
   552 
       
   553 #ifdef _DEBUG_WINDOW
       
   554 		LOG(_L8("Got Frame"));
       
   555 		LOGHEXRAW(frame->Payload().Ptr(), frame->PayloadLength());
       
   556 
       
   557 		LOG(_L8("Slip Encoded Frame"));
       
   558 		LOGHEXRAW(aFrame->Ptr(), aFrame->Length());
       
   559 #endif
       
   560 		}
       
   561 	else
       
   562 		{
       
   563 		// Just in case our return code is ignored :->
       
   564 		aFrame = NULL;
       
   565 		}
       
   566 
       
   567 	return err;
       
   568 	}
       
   569 
       
   570 TBool CHCTLBcspFrameQueue::AckReceived(TInt aAckValue)
       
   571 /**
       
   572 	Handle AckReceived @param aAckValue
       
   573 
       
   574 	call Acknowledged method on relaible queue
       
   575 	call CanSend()
       
   576 
       
   577 	@return ETrue if there are unacknowledged packets remaining
       
   578 	              in the tx window.
       
   579 */
       
   580 	{
       
   581 	LOG_FUNC
       
   582 
       
   583 	TBool ret=iReliableQueue->Acknowledged(aAckValue);
       
   584 	CanSend();
       
   585 	return ret;
       
   586 	}
       
   587 
       
   588 void CHCTLBcspFrameQueue::AckTimeout()
       
   589 /**
       
   590 	Handle Rx Ack timeout
       
   591 	
       
   592 	Inform reliable queue to resend frame
       
   593 	CanSend
       
   594 	Call iSequencer->WakeUp() to trigger the sequencer to pull frames for resending from the
       
   595 	reliable frame queue
       
   596 */
       
   597 	{
       
   598 	LOG_FUNC
       
   599 
       
   600 	iReliableQueue->Acknowledged(KErrTimedOut);
       
   601 	CanSend();
       
   602 	iSequencer->WakeUp();
       
   603 	}
       
   604 
       
   605 TInt CHCTLBcspFrameQueue::AddReliableFrame(const TDesC8 &aData, TUint8 aProtocolId)
       
   606 /**
       
   607 	Method to add a frame to the Tx Reliable queue
       
   608 	@param aData - HCI payload
       
   609 	@param aProtocolId - ProtocolId eg. ACL, Command
       
   610 */
       
   611 	{
       
   612 	TInt err = KErrNone;
       
   613 	LOG_FUNC
       
   614 
       
   615 #ifdef _DEBUG_WINDOW
       
   616 	LOG(_L8("Adding Frame to Reliable Queue"));
       
   617 	LOGHEXDESC(aData);
       
   618 #endif
       
   619 
       
   620 	CTxHctlBcspFrame *frame=iReliableQueue->WriteFrame();
       
   621 	
       
   622 	// A NULL frame is now returned if (on the rare occasion) the frame queue has become blocked.
       
   623 	// The original panic has been replaced by an upward error handling path. 
       
   624 	if (!frame)
       
   625 	 	{
       
   626 	 	err = KErrOverflow;	
       
   627 	 	}
       
   628 	else
       
   629 		{
       
   630 		frame->SetProtocolId(aProtocolId);
       
   631 		frame->SetPayload(aData);
       
   632 		iSequencer->WakeUp();
       
   633 		}
       
   634 	
       
   635 	CanSend();
       
   636 	return err;
       
   637 	
       
   638 	}
       
   639 
       
   640 void CHCTLBcspFrameQueue::AddUnreliableFrame(const TDesC8 &aData, TUint8 aProtocolId, 
       
   641 											 TUint8 aAck,
       
   642 											 TBool aCRCEnabled)
       
   643 /**
       
   644 	Method to add an Unreliable frame to the unreliable frame queue
       
   645 
       
   646 	@param aData - HCI payload
       
   647 	@param aProtocolId
       
   648 	@param aAck
       
   649 	@param aCRCState
       
   650 
       
   651 	Calls wakeup method on the sequencer to trigger frame sending
       
   652 */
       
   653 	{
       
   654 	LOG_FUNC
       
   655 
       
   656 	CTxHctlBcspFrame *frame=iUnreliableQueue->WriteFrame();
       
   657 
       
   658 #ifdef _DEBUG_WINDOW
       
   659 	LOG(_L8("Adding Frame to Unreliable Queue"));
       
   660 #endif
       
   661 
       
   662 	LOGHEXDESC(aData);
       
   663 	if ( frame )
       
   664 		{
       
   665 		frame->SetProtocolId(aProtocolId);
       
   666 		frame->SetPayload(aData);
       
   667 		frame->SetFlags(aAck, aCRCEnabled, EFalse);
       
   668 		}
       
   669 	// else we've got no free slots - therefore since this is an unreliable Frame we can
       
   670 	// just throw it away
       
   671 
       
   672 	iSequencer->WakeUp();
       
   673 	}
       
   674 
       
   675 void CHCTLBcspFrameQueue::AddUnreliableFrame(TUint8 aProtocolId,
       
   676 											 TUint8 aAck,
       
   677 											 TBool aCRCEnabled)
       
   678 /**
       
   679 	Method to add an empty Unreliable frame to the unreliable frame queue
       
   680 	eg. an AckFrame
       
   681 
       
   682 	@param aProtocolId
       
   683 	@param aAck
       
   684 	@param aCRCState
       
   685 
       
   686 */
       
   687 	{
       
   688 	LOG_FUNC
       
   689 
       
   690 	CTxHctlBcspFrame *frame=iUnreliableQueue->WriteFrame();
       
   691 
       
   692 #ifdef _DEBUG_WINDOW
       
   693 	LOG(_L8("Adding Empty Frame to Unreliable Queue"));
       
   694 #endif
       
   695 
       
   696 	if ( frame )
       
   697 		{
       
   698 		frame->SetProtocolId(aProtocolId);
       
   699 		frame->SetPayload();
       
   700 		frame->SetFlags(aAck, aCRCEnabled, EFalse);
       
   701 		}
       
   702 	// else we've got no free slots - therefore since this is an unreliable Frame we can
       
   703 	// just throw it away
       
   704 
       
   705 	iSequencer->WakeUp();
       
   706 
       
   707 	}
       
   708 	
       
   709 void CHCTLBcspFrameQueue::Reset()
       
   710  	{
       
   711 	LOG_FUNC
       
   712 
       
   713  	iReliableQueue->Reset();
       
   714  	iUnreliableQueue->Reset();
       
   715  	}
       
   716  	
       
   717 void CHCTLBcspFrameQueue::CanSend()
       
   718 /**
       
   719 	Kicks packet router
       
   720 	Only reliable queue is checked here for availability because we don't want to flow control 
       
   721 	the unreliable packets. Unreliable packets are simply dropped when the queue is full.
       
   722 */
       
   723 	{
       
   724 	LOG_FUNC
       
   725 
       
   726 	iBcsp.CanSend(iReliableQueue->FreeFrames()>0);
       
   727 	}