bthci/hci2implementations/hctls/bcsp/src/hctlbcsp.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 "hctlbcsp.h"
       
    22 
       
    23 #include "hctlbcspFrameQueue.h"
       
    24 #include "bcsputils.h"
       
    25 #include "hctlbcspframe.h"
       
    26 #include "hctlbcspconsts.h"
       
    27 #include "linkestablishment.h"
       
    28 #include "hctlbcspreceiver.h"
       
    29 #include "hctlbcspsequencer.h"
       
    30 #include "hctlbcspcontrollermanager.h"
       
    31 #include "debug.h"
       
    32 
       
    33 #include <bluetooth/hci/hcierrors.h>
       
    34 #include <bluetooth/hci/hcievents.h>
       
    35 #include <bluetooth/hci/hctlchannelobserver.h>
       
    36 #include <bluetooth/hci/hctldataobserver.h>
       
    37 #include <bluetooth/hci/hctleventobserver.h>
       
    38 
       
    39 /**
       
    40 	Implementation of Class CHCTLBcsp
       
    41 */
       
    42 
       
    43 CHCTLBcsp::CHCTLBcsp()
       
    44 	{
       
    45 	LOG_FUNC
       
    46 	}
       
    47 
       
    48 CHCTLBcsp::~CHCTLBcsp()
       
    49 	{
       
    50 	LOG_FUNC
       
    51 
       
    52 	HCI_LOG_UNLOAD(this);
       
    53 	delete iLinkEstablishment;
       
    54 	delete iReceiver;
       
    55 	delete iSequencer;
       
    56 	delete iFrameQueue;
       
    57 	delete iReceivedFrame;
       
    58 	delete iControllerMan;
       
    59 	}
       
    60 
       
    61 CHCTLBcsp* CHCTLBcsp::NewL()
       
    62 	{
       
    63 	LOG_STATIC_FUNC
       
    64 
       
    65 	CHCTLBcsp* self=new(ELeave) CHCTLBcsp;
       
    66 	CleanupStack::PushL(self);
       
    67 	self->ConstructL();
       
    68 	CleanupStack::Pop(self);
       
    69 	return self;
       
    70 	}
       
    71 
       
    72 void CHCTLBcsp::ConstructL()
       
    73 	{
       
    74 	LOG_FUNC
       
    75 	
       
    76 	HCI_LOG_LOADL(this, KHCILoggerDatalinkTypeH1);	// Technically it's BCSP but we're going
       
    77 													// to log at a higher layer
       
    78 	BaseConstructL(KIniFileName);													
       
    79 	iControllerMan = CHCTLBcspControllerManager::NewL(*this, Port(), PowerCtrlMode());
       
    80 	}
       
    81 
       
    82 TAny* CHCTLBcsp::Interface(TUid aUid)
       
    83 	{
       
    84 	LOG_FUNC
       
    85 
       
    86 	TAny* ret = NULL;
       
    87 	switch(aUid.iUid)
       
    88 		{
       
    89 		case KHCTLInterfaceUid:
       
    90 			ret = reinterpret_cast<TAny*>(static_cast<MHCTLInterface*>(this));
       
    91 			break;
       
    92 		case KHCTLPowerInterfaceUid:
       
    93 			ret = reinterpret_cast<TAny*>(static_cast<MHCTLPowerInterface*>(iControllerMan));
       
    94 			break;
       
    95 		case KHCHardResetUid:
       
    96 			ret = reinterpret_cast<TAny*>(static_cast<MHardResetInitiator*>(this));
       
    97 			break;	
       
    98 		
       
    99 		default:
       
   100 			break;
       
   101 		};
       
   102 
       
   103 	return ret;
       
   104 	}
       
   105 
       
   106 void CHCTLBcsp::DoConfigL()
       
   107 /**
       
   108 	
       
   109 	Method to set the TCommConfigV01 settings for UART based HCTLs
       
   110 	enforced implementation by pure virtual method in CHCTLUartBase to allow for the original uart transport (H4) and BCSP
       
   111 	specific settings
       
   112 
       
   113 	@leave method will leave if Port().SetConfig() fails
       
   114 */
       
   115 	{
       
   116 	LOG_FUNC
       
   117 
       
   118 	Port().ResetBuffers();
       
   119 	TCommConfig conf;
       
   120 	Port().Config(conf);
       
   121 
       
   122 	TCommConfigV01& config = conf(); //Get reference to TCommConfig iConfig
       
   123 
       
   124 	config.iDataBits = EData8;				
       
   125 	config.iStopBits = EStop1; 
       
   126 	config.iTerminatorCount = 1;
       
   127 	config.iTerminator[0] = 0xc0;
       
   128 	config.iParity = EParityEven;				 
       
   129 	config.iParityError = KConfigParityErrorFail;
       
   130 	config.iHandshake = 0; 
       
   131 	config.iXonChar = 0;
       
   132 	config.iXoffChar = 0;
       
   133 	
       
   134 	LEAVEIFERRORL(Port().SetConfig(conf));
       
   135 	}
       
   136 
       
   137 
       
   138 //Implemenation of MHCTLInterface
       
   139 
       
   140 TInt CHCTLBcsp::MhiWriteAclData(const TDesC8& aData)
       
   141 	{
       
   142 	LOG_FUNC
       
   143 	
       
   144 	iFrameQueue->AddReliableFrame(aData, KBcspACLDataChnl);
       
   145 	HCI_LOG_FRAME(this, KHCILoggerHostToController | KHCILoggerACLDataFrame, aData);
       
   146 	return KErrNone;
       
   147 	}
       
   148 
       
   149 TInt CHCTLBcsp::MhiWriteSynchronousData(const TDesC8& aData)
       
   150 	{
       
   151 	LOG_FUNC
       
   152 
       
   153 	iFrameQueue->AddUnreliableFrame(aData, KBcspSynchronousDataChnl, 0, EFalse);
       
   154 	HCI_LOG_FRAME(this, KHCILoggerHostToController | KHCILoggerSynchronousDataFrame, aData);
       
   155 	return KErrNone;
       
   156 	}
       
   157 
       
   158 TInt CHCTLBcsp::MhiWriteCommand(const TDesC8& aData)	
       
   159 	{
       
   160 	LOG_FUNC
       
   161 
       
   162 	TRAPD(err,DoWriteCommandL(aData));
       
   163 	if(err!=KErrNone)
       
   164 		{
       
   165 		return KErrBcspWriteCommandDataFailed;
       
   166 		}
       
   167 	else
       
   168 		{
       
   169 		HCI_LOG_FRAME(this, KHCILoggerHostToController | KHCILoggerCommandOrEvent, aData);
       
   170 		return err;
       
   171 		}
       
   172 	}
       
   173 
       
   174 TInt CHCTLBcsp::WriteBcCmd(const TDesC8& aData)	
       
   175 	{
       
   176 	LOG_FUNC
       
   177 
       
   178 	TRAPD(err,DoWriteBcCmdL(aData));
       
   179 	if(err!=KErrNone)
       
   180 		{
       
   181 		return KErrBcspWriteBcCmdDataFailed;
       
   182 		}
       
   183 	else
       
   184 		{
       
   185 		HCI_LOG_FRAME(this, KHCILoggerHostToController | KHCILoggerCommandOrEvent, aData);
       
   186 		return err;
       
   187 		}
       
   188 	}
       
   189 
       
   190 void CHCTLBcsp::MhiSetQdpPluginInterfaceFinder(MQdpPluginInterfaceFinder& aQdpPluginInterfaceFinder)
       
   191 	{
       
   192 	iQdpPluginInterfaceFinder = &aQdpPluginInterfaceFinder;
       
   193 	}
       
   194 	
       
   195 void CHCTLBcsp::MhriStartHardReset()
       
   196 	{
       
   197 	iControllerMan->HardReset();	
       
   198 	}
       
   199 	
       
   200 void CHCTLBcsp::MhiGetAclDataTransportOverhead(TUint& aHeaderSize, TUint& aTrailerSize) const
       
   201 	{
       
   202 	aHeaderSize = KHCTLAclDataHeaderSize;
       
   203 	aTrailerSize = KHCTLAclDataTrailerSize;
       
   204 	}
       
   205 	
       
   206 
       
   207 void CHCTLBcsp::MhiGetSynchronousDataTransportOverhead(TUint& aHeaderSize, TUint& aTrailerSize) const
       
   208 	{
       
   209 	aHeaderSize = KHCTLSynchronousDataHeaderSize;
       
   210 	aTrailerSize = KHCTLSynchronousDataTrailerSize;
       
   211 	}
       
   212 
       
   213 void CHCTLBcsp::MhiGetCommandTransportOverhead(TUint& aHeaderSize, TUint& aTrailerSize) const
       
   214 	{
       
   215 	aHeaderSize = KHCTLCommandHeaderSize;
       
   216 	aTrailerSize = KHCTLCommandTrailerSize;
       
   217 	}
       
   218 
       
   219 //MHCTLInterface  END
       
   220 
       
   221 
       
   222 void CHCTLBcsp::DoWriteCommandL(const TDesC8 &aData)
       
   223 /**
       
   224 	
       
   225 	Method called from MhiWriteCommand
       
   226 
       
   227 	@param aData
       
   228 	aData is the formatted Command payload from the linkmanager
       
   229 
       
   230 */
       
   231 	{
       
   232 	LOG_FUNC
       
   233 
       
   234 #ifdef __DEBUG_FLOG_STACK_TX_
       
   235 	LOG(_L8("STACK TX"));
       
   236 	LOGHEXDESC(aData);
       
   237 #endif
       
   238 	User::LeaveIfError(iFrameQueue->AddReliableFrame(aData, KBcspCommEvntChnl));//KBcspBcCmdChnl
       
   239 	}
       
   240 
       
   241 void CHCTLBcsp::DoWriteBcCmdL(const TDesC8 &aData)
       
   242 /**
       
   243 	
       
   244 	Method called from WriteBcCmdData
       
   245 
       
   246 	@param aData
       
   247 	aData is the formatted BCCMD payload from the controller manager
       
   248 
       
   249 */
       
   250 	{
       
   251 	LOG_FUNC
       
   252 
       
   253 #ifdef __DEBUG_FLOG_STACK_TX_
       
   254 	LOG(_L8("STACK TX"));
       
   255 	LOGHEXDESC(aData);
       
   256 #endif
       
   257 	User::LeaveIfError(iFrameQueue->AddReliableFrame(aData, KBcspBcCmdChnl));
       
   258 	}
       
   259 
       
   260 /**
       
   261 Process Received data in to the format expected by the interface to the bottom of the stack
       
   262 */
       
   263 
       
   264 void CHCTLBcsp::ProcessACLData() 
       
   265 /**
       
   266 	Passes ACL data to the data observer.
       
   267 */
       
   268 	{
       
   269 	LOG_FUNC
       
   270 
       
   271 	__ASSERT_DEBUG(iReceivedFrame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   272 
       
   273 	HCI_LOG_FRAME(this, KHCILoggerControllerToHost | KHCILoggerACLDataFrame, iReceivedFrame->Payload());
       
   274 	iDataObserver->MhdoProcessAclData(iReceivedFrame->Payload());
       
   275 	}
       
   276 
       
   277 void CHCTLBcsp::ProcessEventData()
       
   278 /**
       
   279 	Passes event data to the data observer.
       
   280 */
       
   281 	{
       
   282 	LOG_FUNC
       
   283 
       
   284 	__ASSERT_DEBUG(iReceivedFrame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   285 
       
   286 	HCI_LOG_FRAME(this, KHCILoggerControllerToHost | KHCILoggerCommandOrEvent, iReceivedFrame->Payload());
       
   287 	iEventObserver->MheoProcessEvent(iReceivedFrame->Payload());
       
   288 	}
       
   289 
       
   290 void CHCTLBcsp::ProcessBcCmdEventData()
       
   291 /**
       
   292 	
       
   293 	Method which parses the received Command data payload from the controller
       
   294 	and formats the data to be passed to the controller manager
       
   295 */
       
   296 	{
       
   297 	LOG_FUNC
       
   298 
       
   299 	__ASSERT_DEBUG(iReceivedFrame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   300 
       
   301 	HCI_LOG_FRAME(this, KHCILoggerControllerToHost | KHCILoggerCommandOrEvent, iReceivedFrame->Payload());
       
   302 	iControllerMan->ProcessBcCmdEvent(iReceivedFrame->Payload());
       
   303 	}
       
   304 
       
   305 void CHCTLBcsp::ProcessSynchronousData()
       
   306 	{
       
   307 	LOG_FUNC
       
   308 
       
   309 	__ASSERT_DEBUG(iReceivedFrame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   310 
       
   311 	HCI_LOG_FRAME(this, KHCILoggerControllerToHost | KHCILoggerSynchronousDataFrame, iReceivedFrame->Payload());
       
   312 	iDataObserver->MhdoProcessSynchronousData(iReceivedFrame->Payload());
       
   313 	}
       
   314 
       
   315 TInt CHCTLBcsp::PacketRouter()
       
   316 /**
       
   317 	Method called by CHCTLBcspReceiver after packet integrity checks have been performed
       
   318 	This routes packets according to the ProtocolId associated with the payload type in a 
       
   319 	given BCSP frame to the appropriate interface to the top of the HCI and thus to the 
       
   320 	link manager
       
   321 */
       
   322 	{
       
   323 	LOG_FUNC
       
   324 
       
   325 	TInt err = KErrNone;
       
   326 	__ASSERT_DEBUG(iReceivedFrame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   327 
       
   328 	switch (iReceivedFrame->ProtocolId())
       
   329 		{
       
   330 		case KBcspCommEvntChnl:
       
   331 			{
       
   332 			LOG(_L8("HCTLBCSP: Event Packet Received..."));
       
   333 			ProcessEventData();
       
   334 			}
       
   335 			break;
       
   336 
       
   337 		case KBcspBcCmdChnl:
       
   338 			{
       
   339 			LOG(_L8("HCTLBCSP: BC Command Packet Received..."));
       
   340 			ProcessBcCmdEventData();
       
   341 			}
       
   342 			break;
       
   343 
       
   344 		case KBcspACLDataChnl:
       
   345 			{
       
   346 			LOG(_L8("HCTLBCSP: ACL Data Packet Received..."));
       
   347 			ProcessACLData();
       
   348 			}
       
   349 			break;
       
   350 
       
   351 		case KBcspSynchronousDataChnl:
       
   352 			{
       
   353 			LOG(_L8("HCTLBCSP: Synchronous Data Packet Received..."));
       
   354 			ProcessSynchronousData();
       
   355 			}
       
   356 			break;
       
   357 
       
   358 		case KBcspLinkChnl:
       
   359 			{
       
   360 			LOG(_L8("HCTLBCSP: Link Est Packet Received..."));
       
   361 			__ASSERT_DEBUG(iLinkEstablishment!=NULL, PANIC(KBcspPanicCat, EBadLinkPointer));
       
   362 			TRAP(err,iLinkEstablishment->ProcessLinkMsg(iReceivedFrame->Payload()));
       
   363 			}	
       
   364 			break;
       
   365 
       
   366 		default:
       
   367 			LOG(_L8("HCTLBCSP: ERROR: KErrBcspUnRecognizableHCIData..."));
       
   368 			break;
       
   369 		};
       
   370 		
       
   371 	return err;
       
   372 	}
       
   373 
       
   374 void CHCTLBcsp::QueueReadForNextFrame()
       
   375 	{
       
   376 	LOG_FUNC
       
   377 
       
   378 	iReceiver->QueueReadForNextFrame();
       
   379 	}
       
   380 
       
   381 void CHCTLBcsp::CanSend(TBool aCanSend)
       
   382 /**
       
   383 	For BCSP this is always taken to be all channels or no channels
       
   384 */
       
   385 	{
       
   386 	LOG_FUNC
       
   387 
       
   388 	iCanSend = aCanSend;
       
   389 	// We can only open the channel after unchoked and iChannelObserver has been set
       
   390 	if(!iChoked && iChannelObserver)
       
   391 		{
       
   392 		if(iCanSend)
       
   393 			{
       
   394 			iChannelObserver->MhcoChannelOpen(KHCITransportAllChannels);
       
   395 			}
       
   396 		else
       
   397 			{
       
   398 			iChannelObserver->MhcoChannelClosed(KHCITransportAllChannels);
       
   399 			}
       
   400 		}
       
   401 	}
       
   402 
       
   403 void CHCTLBcsp::TxAckMsg()
       
   404 /**
       
   405 	Method to send a BCSP Ack message
       
   406 	This is only called when an the Ack timer fires i.e. a certain amount of time has
       
   407 	passed without there being an outgoing BCSP frame to convey acknowledgement of received 
       
   408 	reliable frames
       
   409 */
       
   410 	{	
       
   411 	LOG_FUNC
       
   412 
       
   413 	iFrameQueue->AddUnreliableFrame(KBcspAckChnl, iSequencer->TxAck(), EFalse);
       
   414 	}
       
   415 
       
   416 void CHCTLBcsp::TxLinkMsg(const TDesC8& aData)
       
   417 /**
       
   418 	
       
   419 	This is a method that takes a BCSP Link Establishment message as its parameter
       
   420 	and adds the data along with a number of other bits of information to make a frame 
       
   421 	on the Unreliable frame queue via the iFrameQueue::AddUnreliableFrame() method
       
   422 */
       
   423 	{	
       
   424 	LOG_FUNC
       
   425 
       
   426 	iFrameQueue->AddUnreliableFrame(aData, KBcspLinkChnl, 0, ETrue);
       
   427 	}
       
   428 
       
   429 TInt CHCTLBcsp::HandleRx(const TDesC8 &aReceivedFrame)
       
   430 /**
       
   431 	
       
   432 	This is a method called from the CHCTLBcspReceiver::ProcessDataL()
       
   433 	with the parameter
       
   434 	@param const TDesC8 &aReceivedFrame
       
   435 	@return err
       
   436 	This method attempts to slip decode the received frame 
       
   437 	Then if that is successful the remainder of the BCSP frame integrity checks are performed
       
   438 	using the iReceivedFrame->IsValid() method
       
   439 	Assuming that this all works without errors control is then passed to the sequencer
       
   440 	via the iSequencer->HandleRx(iReceivedFrame) call
       
   441 	and then the iReceivedFrame->Reset() method is called
       
   442 */
       
   443 	{
       
   444 	LOG_FUNC
       
   445 
       
   446 	TInt rerr = iReceivedFrame->SlipDecodeFrame(aReceivedFrame);
       
   447 	if (rerr == KErrNone)
       
   448 		{
       
   449 		// We've succeeded in decoding the Slip Frame into a CRxHctlBcspFrame
       
   450 		__ASSERT_DEBUG(iReceivedFrame->IsValid(), PANIC(KBcspPanicCat, EBadBcspFrame));
       
   451 
       
   452 #ifdef __DEBUG_RxDecodedFrame__
       
   453 		FlogRx();
       
   454 #endif
       
   455 
       
   456 		iSequencer->HandleRx(iReceivedFrame);
       
   457 		iReceivedFrame->Reset();
       
   458 		}
       
   459 
       
   460 	return rerr;
       
   461 	}
       
   462 
       
   463 TBool CHCTLBcsp::CheckIsAckPacket() const
       
   464 /**
       
   465 	
       
   466 	This is a relatively simple method that examines the ProtocolId of the Received Frame
       
   467 	and attempts to match it to the the KBcspAckChnl constant and then returns a TBool depending
       
   468 	on whether or not these match
       
   469 */
       
   470 	{
       
   471 	LOG_FUNC
       
   472 
       
   473 	return (iReceivedFrame->ProtocolId() == KBcspAckChnl);
       
   474 	}
       
   475 
       
   476 #ifdef __DEBUG_RxDecodedFrame__
       
   477 void CHCTLBcsp::FlogRx()
       
   478 	{
       
   479 	LOG(_L8("RxFrame"));
       
   480 	LOG1(_L8("Protocol type reliable(1) unreliable (0) = %d\n"),iReceivedFrame->IsReliableProtcolType());
       
   481 	LOG1(_L8("Ack value = %d\n"),iReceivedFrame->Ack());
       
   482 	LOG1(_L8("Seq value = %d\n"),iReceivedFrame->Sequence());
       
   483 	LOG1(_L8("Protocol ID (Command/Event(5)) (ACL) (Ack Packet) = %d\n"),iReceivedFrame->ProtocolId());
       
   484 	LOG1(_L8("Payload Length = %d\n"),iReceivedFrame->PayloadLength());
       
   485 	LOG1(_L8("Checksum value = %d\n"),iReceivedFrame->CheckSum());
       
   486 	LOG1(_L8("Header bytes = %d\n"),iReceivedFrame->FlagsField());
       
   487 	LOG(_L8("Payload..."));
       
   488 	LOGHEXDESC(iReceivedFrame->Payload());
       
   489 	}
       
   490 #endif
       
   491 
       
   492 
       
   493 
       
   494 /**
       
   495 	See comments on iChoked	
       
   496 */
       
   497 void CHCTLBcsp::Choke()
       
   498 	{
       
   499 	LOG_FUNC
       
   500 
       
   501 	iChoked = ETrue;
       
   502 	CanSend(iCanSend);
       
   503 	}
       
   504 
       
   505 /**
       
   506 	See comments on iChoked	
       
   507 */
       
   508 void CHCTLBcsp::UnChoke()
       
   509 	{
       
   510 	LOG_FUNC
       
   511 
       
   512 	iChoked = EFalse;
       
   513 	if(iControllerMan->BcspLinkEstablished())
       
   514 		{
       
   515 		CanSend(iCanSend);
       
   516 		}
       
   517 	}
       
   518 
       
   519 TBool CHCTLBcsp::Muzzled()
       
   520 	{
       
   521 	return iMuzzled;
       
   522 	}
       
   523 
       
   524 void CHCTLBcsp::ResetMuzzled()
       
   525 	{
       
   526 	iMuzzled = EFalse;
       
   527 	}
       
   528 
       
   529 /**
       
   530 
       
   531 	Handle a reset of the BCSP transport.
       
   532 	1) Reset the BCSP layer
       
   533 	2) Inform the stack of a HCI error
       
   534 	3) Stack will reinitialise with a "reset" command etc
       
   535 */
       
   536 void CHCTLBcsp::HandlePeerReset()
       
   537 	{
       
   538 	LOG_FUNC
       
   539 
       
   540 	// If a poweroff is requested, the next reset will lead to a reset of the SP link
       
   541 	// and will set the state to shy sending a sync frame every 250ms
       
   542 	// So, Muzzle the host to avoid sending this command 
       
   543 	if(iControllerMan->PowerOffRequested())
       
   544 		{
       
   545 		iMuzzled = ETrue;
       
   546 		}
       
   547 
       
   548 	Reset(); //reset BCSP
       
   549 	
       
   550 	if(!iControllerMan->ExpectedControllerReset() && !iControllerMan->PowerOffRequested())
       
   551 		{
       
   552 		// Inform stack of hardware error	
       
   553 		TUint8 errReason = static_cast<TUint8>(EInvalidHCIParameter);
       
   554 		TBuf8<3> buf(3);
       
   555 		buf[0]= EHardwareErrorEvent; //error code
       
   556 		buf[1] = 1; //length
       
   557 		buf[2] = errReason; //parameter
       
   558 		iEventObserver->MheoProcessEvent(buf);	
       
   559 		}
       
   560 	}
       
   561 
       
   562 /**
       
   563 	Reset the BCSP layer
       
   564 */
       
   565 void CHCTLBcsp::Reset()
       
   566 	{
       
   567 	LOG_FUNC
       
   568 
       
   569 	Choke();	//Disconnected
       
   570 	//Reset the link establishment state machine
       
   571 	iLinkEstablishment->Reset();
       
   572 	//Reset and clear transmit queues
       
   573 	iFrameQueue->Reset();
       
   574 	//Reset the sequencer
       
   575 	iSequencer->Reset();
       
   576 	}
       
   577 
       
   578 //Implementation of pure virtual functions in CHCTLUartBase
       
   579 
       
   580 void CHCTLBcsp::PortOpenedL()
       
   581 	{
       
   582 	LOG_FUNC
       
   583 
       
   584 	__ASSERT_DEBUG(Port().Handle(), PANIC(KBcspPanicCat, EPortNotOpen));
       
   585 		
       
   586 	DoConfigL();
       
   587 	
       
   588 	
       
   589 	iChoked = ETrue;
       
   590 
       
   591 	iFrameQueue = CHCTLBcspFrameQueue::NewL(*this);
       
   592 
       
   593 	// Creation of the sequencer creates the sender Active Object. 
       
   594 	// The sender Active Object must be added to the Active Scheduler before 
       
   595 	// the receiver Active Object so that it gets preferential treatment. It 
       
   596 	// is reported that otherwise the response from a command can come in 
       
   597 	// before the sending client is told that the send has completed!
       
   598 	iSequencer = CHCTLBcspSequencer::NewL(*this, Port(), *iFrameQueue);
       
   599 	iReceiver=CHCTLBcspReceiver::NewL(*this, Port());
       
   600 
       
   601 	iFrameQueue->SetSequencer(*iSequencer);
       
   602 
       
   603 	iLinkEstablishment= CLinkEstablishment::NewL(*this);
       
   604 
       
   605 	iReceivedFrame = CRxHctlBcspFrame::NewL();
       
   606 	}
       
   607 
       
   608 void CHCTLBcsp::MhiSetDataObserver(MHCTLDataObserver& aDataObserver)
       
   609 	{
       
   610 	iDataObserver = &aDataObserver;
       
   611 	}
       
   612 
       
   613 void CHCTLBcsp::MhiSetEventObserver(MHCTLEventObserver& aEventObserver)
       
   614 	{
       
   615 	iEventObserver = &aEventObserver;
       
   616 	}
       
   617 
       
   618 void CHCTLBcsp::MhiSetChannelObserver(MHCTLChannelObserver& aChannelObserver)
       
   619 	{
       
   620 	iChannelObserver = &aChannelObserver;
       
   621 	//give the stack an initial kick
       
   622 	CanSend(iCanSend);
       
   623 	}
       
   624 
       
   625 void CHCTLBcsp::MhiSetControllerStateObserver(MControllerStateObserver& aControllerStateObserver)
       
   626 	{
       
   627 	iControllerStateObserver = &aControllerStateObserver;
       
   628 	iControllerMan->SetObserver(aControllerStateObserver);
       
   629 	iControllerMan->Start();
       
   630 	}