bluetoothengine/btsac/btrcc/src/btrccLinker.cpp
changeset 0 f63038272f30
child 9 a42ed326b458
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  State Machine of BTRCC
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <remconaddress.h>
       
    20 #include <remconbeareravrcp.h> //	KRemConBearerAvrcpImplementationUid = 0x1020685f
       
    21 #include <btaccObserver.h>
       
    22 #include <remconinterfaceselector.h>  
       
    23 #include <remconaddress.h> 
       
    24 #include <remconcoreapitarget.h>
       
    25 #include <apacmdln.h>
       
    26 #include <apgcli.h>
       
    27 #include "btaudioremconpskeys.h"
       
    28 #include "btrccLegacyVolumeLevelController.h"
       
    29 #include "btrccAbsoluteVolumeLevelController.h"
       
    30 #include "btrccLinker.h"
       
    31 #include "btrccplayerstarter.h"
       
    32 #include "btrccBrowsingAdapter.h"
       
    33 #include "debug.h"
       
    34 #include <btnotif.h>
       
    35 #include <mmf/server/sounddevice.h>
       
    36 
       
    37 #include "prjconfig.h"
       
    38 
       
    39 #ifdef PRJ_MODULETEST_BUILD
       
    40 const TInt KAvrcpBearerUid = 0xEEEEAAAA;
       
    41 #else
       
    42 const TInt KAvrcpBearerUid = KRemConBearerAvrcpImplementationUid;
       
    43 #endif
       
    44 
       
    45 const TInt KMaxRetries = 3;
       
    46 // MODULE DATA STRUCTURES
       
    47 
       
    48 // ================= MEMBER FUNCTIONS =======================
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // CBTRCCLinker::NewL
       
    52 // Two-phased constructor.
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 CBTRCCLinker* CBTRCCLinker::NewL(MBTAccObserver& aAccObserver)
       
    56     {
       
    57     CBTRCCLinker* self = new (ELeave) CBTRCCLinker(aAccObserver);
       
    58     CleanupStack::PushL(self);
       
    59     self->ConstructL();
       
    60     CleanupStack::Pop(self);
       
    61     return self;
       
    62     }
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CBTRCCLinker::CBTRCCLinker
       
    66 // C++ constructor.
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 CBTRCCLinker::CBTRCCLinker(MBTAccObserver& aAccObserver)
       
    70     : CActive(EPriorityNormal), iAccObserver(aAccObserver)
       
    71 	{
       
    72 	CActiveScheduler::Add(this);
       
    73 	}
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CBTRCCLinker::ConstructL
       
    77 // Symbian 2nd phase constructor.
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 void CBTRCCLinker::ConstructL()
       
    81 	{
       
    82     TRACE_FUNC_ENTRY
       
    83 
       
    84     iInterfaceSelector = CRemConInterfaceSelector::NewL();
       
    85     iVolController = NULL;
       
    86     iRegisterVolumeChangeNotificationCounter = 0;
       
    87     if (iAccObserver.IsAvrcpVolCTSupported())
       
    88         {
       
    89         iAbsoluteVolController = CBTRCCAbsoluteVolumeLevelController::NewL(*iInterfaceSelector, *this);
       
    90         iLegacyVolController = CBTRCCLegacyVolumeLevelController::NewL(*iInterfaceSelector, *this);
       
    91         }
       
    92     else 
       
    93    		{
       
    94         // If volume control is not supported, we'll need another interface selector session for disconnecting. 
       
    95         iInterfaceSelectorForDisconnectingTargetSession = CRemConInterfaceSelector::NewL(); 
       
    96     	}
       
    97     
       
    98     iPlayerStarter = CPlayerStarter::NewL();
       
    99     iCoreTarget = CRemConCoreApiTarget::NewL(*iInterfaceSelector, *iPlayerStarter);
       
   100     iPlayerStarter->SetCoreTarget(*iCoreTarget);
       
   101 
       
   102     iRemConBatteryTgt = CRemConBatteryApiTarget::NewL(*iInterfaceSelector, *this);
       
   103 
       
   104 //    iBrowsingAdapter = CBTRCCBrowsingAdapter::NewL(*iInterfaceSelector); 
       
   105     
       
   106     if (iAccObserver.IsAvrcpVolCTSupported()) 
       
   107         {
       
   108         iInterfaceSelector->OpenControllerL();
       
   109         }
       
   110     iInterfaceSelector->OpenTargetL(); 
       
   111 
       
   112     // The insert order matters
       
   113     LEAVE_IF_ERROR(iStateArray.Insert(new (ELeave) TStateIdle(*this), EStateIndexIdle));
       
   114     LEAVE_IF_ERROR(iStateArray.Insert(new (ELeave) TStateConnecting(*this), EStateIndexConnecting));
       
   115     LEAVE_IF_ERROR(iStateArray.Insert(new (ELeave) TStateConnected(*this), EStateIndexConnected));
       
   116     LEAVE_IF_ERROR(iStateArray.Insert(new (ELeave) TStateDisconnect(*this), EStateIndexDisconnect));
       
   117     ChangeState(EStateIndexIdle);
       
   118 	TRACE_FUNC_EXIT
       
   119     }
       
   120 
       
   121 // -----------------------------------------------------------------------------
       
   122 // Destructor.
       
   123 // -----------------------------------------------------------------------------
       
   124 //
       
   125 CBTRCCLinker::~CBTRCCLinker()
       
   126 	{
       
   127 	TRACE_FUNC_ENTRY
       
   128     if (iClientRequest)
       
   129         User::RequestComplete(iClientRequest, KErrAbort);
       
   130 	
       
   131     delete iAbsoluteVolController;
       
   132     delete iLegacyVolController;
       
   133 	delete iPlayerStarter;
       
   134 	Cancel();
       
   135     iStateArray.ResetAndDestroy();
       
   136     iStateArray.Close();
       
   137 	delete iInterfaceSelector;
       
   138 	delete iInterfaceSelectorForDisconnectingTargetSession; 
       
   139 	TRACE_FUNC_EXIT
       
   140 	}
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // CBTRCCLinker::Connect
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 void CBTRCCLinker::Connect(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
       
   147     {
       
   148     TRACE_FUNC
       
   149     if ( !iAccObserver.IsAvrcpVolCTSupported() )
       
   150         {
       
   151         aStatus = KRequestPending;
       
   152         TRequestStatus* ptr = &aStatus;
       
   153         User::RequestComplete( ptr, KErrNotSupported );
       
   154         }
       
   155     else
       
   156         {
       
   157         TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   158         iStateArray[iCurrentStateIndex]->Connect(aAddr, aStatus);
       
   159         }
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CBTRCCLinker::CancelConnect
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void CBTRCCLinker::CancelConnect(const TBTDevAddr& aAddr)
       
   167     {
       
   168     TRACE_FUNC
       
   169     TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   170     iStateArray[iCurrentStateIndex]->CancelConnect(aAddr);
       
   171     }
       
   172 
       
   173 // -----------------------------------------------------------------------------
       
   174 // CBTRCCLinker::Disconnect
       
   175 // -----------------------------------------------------------------------------
       
   176 //
       
   177 void CBTRCCLinker::Disconnect(TRequestStatus& aStatus, const TBTDevAddr& aAddr)
       
   178     {
       
   179     TRACE_FUNC
       
   180     TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   181     iStateArray[iCurrentStateIndex]->Disconnect(aStatus, aAddr);
       
   182    	}
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // CBTRCCLinker::ActivateRemoteVolumeControl
       
   186 // -----------------------------------------------------------------------------
       
   187 //
       
   188 void CBTRCCLinker::ActivateRemoteVolumeControl()
       
   189     {
       
   190 	TRACE_FUNC
       
   191     TRACE_ASSERT(iAccObserver.IsAvrcpVolCTSupported(), EBtrccPanicAvrcpVolCTNotSupported)
       
   192     if (!iRvcActivated)
       
   193         {
       
   194         iRvcActivated = ETrue;
       
   195         TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   196         iStateArray[iCurrentStateIndex]->UpdateRemoteVolumeControling(iRvcActivated);
       
   197         }
       
   198     }
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // CBTRCCLinker::DeActivateRemoteVolumeControl
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 void CBTRCCLinker::DeActivateRemoteVolumeControl()
       
   205     {
       
   206     TRACE_FUNC
       
   207     TRACE_ASSERT(iAccObserver.IsAvrcpVolCTSupported(), EBtrccPanicAvrcpVolCTNotSupported)
       
   208     if (iRvcActivated)
       
   209         {
       
   210         iRvcActivated = EFalse;
       
   211         TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   212         iStateArray[iCurrentStateIndex]->UpdateRemoteVolumeControling(iRvcActivated);
       
   213         }
       
   214     }
       
   215 
       
   216 // -----------------------------------------------------------------------------
       
   217 // CBTRCCLinker::RunL
       
   218 // -----------------------------------------------------------------------------
       
   219 //
       
   220 void CBTRCCLinker::RunL()
       
   221 	{
       
   222 	TRACE_INFO((_L("CBTRCCLinker::RunL, %d"), iStatus.Int()))
       
   223     TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   224     iStateArray[iCurrentStateIndex]->RemConRequestCompleted(iStatus.Int());
       
   225     }
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CBTRCCLinker::RunError
       
   229 // -----------------------------------------------------------------------------
       
   230 //
       
   231 TInt CBTRCCLinker::RunError(TInt aError)
       
   232     {
       
   233     TRACE_INFO((_L("CBTRCCLinker::RunError, %d"), aError))
       
   234     (void) aError;
       
   235     return KErrNone;
       
   236     }
       
   237 
       
   238 // -----------------------------------------------------------------------------
       
   239 // CBTRCCLinker::DoCancel
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 void CBTRCCLinker::DoCancel()
       
   243     {
       
   244     TRACE_FUNC
       
   245     TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   246     iStateArray[iCurrentStateIndex]->DoCancel();
       
   247     }
       
   248 
       
   249 // -----------------------------------------------------------------------------
       
   250 // CBTRCCLinker::AccObserver
       
   251 // -----------------------------------------------------------------------------
       
   252 //
       
   253 MBTAccObserver& CBTRCCLinker::AccObserver()
       
   254     {
       
   255     return iAccObserver;
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CBTRCCLinker::DoConnect
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 void CBTRCCLinker::DoConnect()
       
   263     {
       
   264     TRACE_FUNC
       
   265 	TRACE_ASSERT(!IsActive(), EBtrccPanicAOIsActive)
       
   266 	DoRemConOrientation();
       
   267 	if (iRemConOriented)
       
   268 		{
       
   269     	iInterfaceSelector->ConnectBearer(iStatus);
       
   270     	SetActive();
       
   271 		}
       
   272 	else
       
   273 	    {
       
   274         TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   275         iStateArray[iCurrentStateIndex]->RemConRequestCompleted(KErrCouldNotConnect);	    
       
   276 	    }
       
   277     }
       
   278 
       
   279 // -----------------------------------------------------------------------------
       
   280 // CBTRCCLinker::DoSubscribeConnetionStatus
       
   281 // -----------------------------------------------------------------------------
       
   282 //
       
   283 void CBTRCCLinker::DoSubscribeConnetionStatus()
       
   284     {
       
   285     TRACE_FUNC
       
   286 	TRACE_ASSERT(!IsActive(), EBtrccPanicAOIsActive)
       
   287 	iInterfaceSelector->NotifyConnectionsChange(iStatus);
       
   288 	SetActive();
       
   289     }
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CBTRCCLinker::DoCancelSubscribe
       
   293 // -----------------------------------------------------------------------------
       
   294 //
       
   295 void CBTRCCLinker::DoCancelSubscribe()
       
   296     {
       
   297     TRACE_FUNC
       
   298     Cancel();
       
   299     }
       
   300 
       
   301 // -----------------------------------------------------------------------------
       
   302 // CBTRCCLinker::DoDisconnect
       
   303 // -----------------------------------------------------------------------------
       
   304 //
       
   305 void CBTRCCLinker::DoDisconnect()
       
   306     {
       
   307     TRACE_FUNC
       
   308 	TRACE_ASSERT(!IsActive(), EBtrccPanicAOIsActive)
       
   309 	TInt err = KErrNone;
       
   310     
       
   311     // if AVRCP RVC is supported, we use InterfaceSelector to do disconnect.
       
   312 	if (iAccObserver.IsAvrcpVolCTSupported())
       
   313 	    {
       
   314 	    err = DoRemConOrientation();
       
   315 	    }
       
   316 	else
       
   317 	    {
       
   318 	    // if AVRCP RVC is not supported, we must be a RemCon Controller for the 
       
   319 	    // disconnected. Use inner RemCon Controller here for not disturbing 
       
   320 	    // interfaceSelector.
       
   321         TRAP(err, iInterfaceSelectorForDisconnectingTargetSession->OpenControllerL()); 
       
   322         TRACE_INFO((_L("open iInterfaceSelectorForDisconnectingTargetSession controller %d"), err))
       
   323         if (!err)
       
   324             {
       
   325             TRemConAddress addr;
       
   326             addr.BearerUid() = TUid::Uid( KAvrcpBearerUid );
       
   327             addr.Addr() = iRemoteAddr.Des();
       
   328             TRAP(err, iInterfaceSelectorForDisconnectingTargetSession->GoConnectionOrientedL(addr));
       
   329             TRACE_INFO((_L("InterfaceSelectorForDisconnectingTargetSession GoConnectionOrientedL %d"), err))
       
   330             }    
       
   331 	    }
       
   332 	
       
   333 	if (!err)
       
   334 		{
       
   335 		if (iAccObserver.IsAvrcpVolCTSupported())
       
   336 		    {
       
   337 		    iInterfaceSelector->DisconnectBearer(iStatus);
       
   338 		    }
       
   339 		else
       
   340 		    {
       
   341             iInterfaceSelectorForDisconnectingTargetSession->DisconnectBearer(iStatus);
       
   342 		    }
       
   343     	SetActive();
       
   344 		}
       
   345 	else
       
   346 	    {
       
   347         TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   348         iStateArray[iCurrentStateIndex]->RemConRequestCompleted(KErrCouldNotConnect);	    
       
   349 	    }
       
   350    	}
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // CBTRCCLinker::ChangeState
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 void CBTRCCLinker::ChangeState(TBTRCCStateIndex aNextState)
       
   357     {
       
   358 	TRACE_INFO((_L("CBTRCCLinker::ChangeState, STATE from %d to %d"), iCurrentStateIndex, aNextState))
       
   359     iCurrentStateIndex = aNextState;
       
   360 	TRACE_ASSERT(iCurrentStateIndex < iStateArray.Count(), EBtrccPanicOutOfRangeState);
       
   361     iStateArray[iCurrentStateIndex]->Enter();
       
   362     }
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // CBTRCCLinker::DoRemConOrientation
       
   366 // -----------------------------------------------------------------------------
       
   367 //
       
   368 TInt CBTRCCLinker::DoRemConOrientation()
       
   369     {
       
   370     TRACE_FUNC
       
   371     TInt err(KErrNone);
       
   372 	// the oriented remote might be a different device than the currently requested,
       
   373     // Go connectionless first.
       
   374 	if (iRemConOriented)
       
   375 	    {
       
   376 	    TRAP(err, iInterfaceSelector->GoConnectionlessL());
       
   377     	iRemConOriented = EFalse;
       
   378 	    if (err)
       
   379 	        {
       
   380 	        TRACE_INFO((_L("GoConnectionless ret %d"), err))
       
   381             return err;
       
   382 	        }
       
   383 	    }
       
   384 	TRemConAddress addr;
       
   385 	addr.BearerUid() = TUid::Uid( KAvrcpBearerUid );
       
   386 	addr.Addr() = iRemoteAddr.Des();
       
   387     TRAP(err, iInterfaceSelector->GoConnectionOrientedL(addr));
       
   388     TRACE_INFO((_L("GoConnectionOriented ret %d"), err))
       
   389     if (!err)
       
   390         {
       
   391         iRemConOriented = ETrue;
       
   392         }
       
   393     return err;
       
   394     }
       
   395 
       
   396 // -----------------------------------------------------------------------------
       
   397 // CBTRCCLinker::DoGetRemConConnectionStatus
       
   398 // -----------------------------------------------------------------------------
       
   399 //
       
   400 void CBTRCCLinker::DoGetRemConConnectionStatus(RArray<TBTDevAddr>& aConnects)
       
   401     {
       
   402 	TRACE_FUNC
       
   403 	TSglQue<TRemConAddress> connections;
       
   404 	aConnects.Reset();
       
   405 	if (iInterfaceSelector->GetConnections(connections) == KErrNone)
       
   406 		{
       
   407 		TSglQueIter<TRemConAddress> iter(connections);
       
   408 		TRemConAddress* addr;
       
   409 		while((addr=iter++) != NULL)
       
   410 			{
       
   411 			if(addr->BearerUid() == TUid::Uid( KAvrcpBearerUid ) )
       
   412 				{
       
   413 				// We have a BT Connection 
       
   414 				if ((addr->Addr().Length() == KBTDevAddrSize) && (TBTDevAddr(addr->Addr()) != TBTDevAddr()))
       
   415 				    {
       
   416     				TRACE_INFO(_L("RemCon bearer found from connections list"));
       
   417     				aConnects.Append(TBTDevAddr(addr->Addr()));
       
   418 				    }
       
   419 				}
       
   420 			// We've copied the information we need, so delete
       
   421 			delete addr;
       
   422 			}
       
   423 		}
       
   424 	else
       
   425 		{
       
   426 		TRACE_INFO(_L("GetNotificationStatus(): FAILED !!!"));
       
   427 		}
       
   428     }
       
   429 
       
   430 // -----------------------------------------------------------------------------
       
   431 // CBTRCCLinker::StartRemoteVolumeControl
       
   432 // -----------------------------------------------------------------------------
       
   433 //
       
   434 void CBTRCCLinker::StartRemoteVolumeControl()
       
   435     {
       
   436     TRACE_FUNC
       
   437     if (iAccObserver.IsAvrcpVolCTSupported())
       
   438         {
       
   439         // Choose based on SDP result whether to create 
       
   440         // absolute controller or legacy controller.
       
   441         if(!iVolController)
       
   442             {
       
   443             if (iAccObserver.IsAbsoluteVolumeSupported(iRemoteAddr))
       
   444                 {
       
   445                 iVolController = iAbsoluteVolController;
       
   446                 }
       
   447             else 
       
   448                 {
       
   449                 iVolController = iLegacyVolController;
       
   450                 }
       
   451             }
       
   452         }
       
   453     if (iVolController)
       
   454         {
       
   455         iVolController->Start();
       
   456         }
       
   457     }
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // CBTRCCLinker::StopRemoteVolumeControl
       
   461 // -----------------------------------------------------------------------------
       
   462 //
       
   463 void CBTRCCLinker::StopRemoteVolumeControl()
       
   464     {
       
   465     TRACE_FUNC
       
   466     if (iVolController)
       
   467         {
       
   468         iVolController->Stop();
       
   469         }
       
   470     }
       
   471 
       
   472 // -----------------------------------------------------------------------------
       
   473 // CBTRCCLinker::ResetVolmeControlSetting
       
   474 // -----------------------------------------------------------------------------
       
   475 //
       
   476 void CBTRCCLinker::ResetVolmeControlSetting()
       
   477     {
       
   478     TRACE_FUNC
       
   479     if (iVolController)
       
   480         {
       
   481         iVolController->Reset();
       
   482         }
       
   483     }
       
   484 
       
   485 // -----------------------------------------------------------------------------
       
   486 // CBTRCCLinker::VolumeControlError
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 void CBTRCCLinker::VolumeControlError(TInt aError)
       
   490     {
       
   491     // This is called if there's an error with sending the volume commands out.
       
   492     switch(aError)
       
   493         {
       
   494         case ERegisterNotificationsFailed:
       
   495             if (iVolController && iRegisterVolumeChangeNotificationCounter<KMaxRetries)
       
   496                 {
       
   497                 iRegisterVolumeChangeNotificationCounter++;
       
   498                 iVolController->RegisterVolumeChangeNotification();
       
   499                 }
       
   500             else
       
   501                 {
       
   502                 iRegisterVolumeChangeNotificationCounter = 0;
       
   503                 }
       
   504             break;
       
   505         case EVolumeAdjustmentFailed:
       
   506         default:
       
   507             {
       
   508             StopRemoteVolumeControl();
       
   509             StartRemoteVolumeControl();
       
   510             break;
       
   511             }
       
   512         }
       
   513     }
       
   514 
       
   515 // -----------------------------------------------------------------------------
       
   516 // CBTRCCLinker::MrcbstoBatteryStatus
       
   517 // -----------------------------------------------------------------------------
       
   518 //
       
   519 void CBTRCCLinker::MrcbstoBatteryStatus(TControllerBatteryStatus& aBatteryStatus)
       
   520 	{
       
   521 	RDebug::Printf("CBmbPlugin::MrcbstoBatteryStatus(), aBatteryStatus = %d",aBatteryStatus);
       
   522 	TBool showBatteryNote(EFalse);
       
   523 
       
   524 	TBTGenericInfoNotiferParamsPckg pckg;
       
   525 	pckg().iRemoteAddr.Copy(iRemoteAddr.Des());
       
   526 	switch(aBatteryStatus)
       
   527 		{
       
   528 		case EWarning:
       
   529 		    pckg().iMessageType = ECmdShowBtBatteryLow;
       
   530 		    showBatteryNote = ETrue;
       
   531 		    break; 
       
   532 		case ECritical:
       
   533 		    pckg().iMessageType = ECmdShowBtBatteryCritical;
       
   534 		    showBatteryNote = ETrue;
       
   535 		    break; 
       
   536 		default: 
       
   537 		    break; 
       
   538 		}
       
   539 
       
   540 	if (showBatteryNote)
       
   541 	    {
       
   542 		RNotifier notifier;
       
   543 		TInt err = notifier.Connect();	
       
   544 		if (!err )
       
   545 		    {
       
   546 		    TRequestStatus status;
       
   547 		    notifier.StartNotifierAndGetResponse(status, KBTGenericInfoNotifierUid, pckg, pckg);
       
   548 		    User::WaitForRequest(status);
       
   549 		    notifier.Close();
       
   550 		    }
       
   551 	    }
       
   552 	}
       
   553 
       
   554 // ================= TState MEMBER FUNCTIONS =======================
       
   555 
       
   556 // -----------------------------------------------------------------------------
       
   557 // CBTRCCLinker::TState::TState
       
   558 // -----------------------------------------------------------------------------
       
   559 //
       
   560 CBTRCCLinker::TState::TState(CBTRCCLinker& aParent)
       
   561 :   iParent(aParent)
       
   562     {
       
   563     }
       
   564 
       
   565 // -----------------------------------------------------------------------------
       
   566 // CBTRCCLinker::TState::DoCancel
       
   567 // -----------------------------------------------------------------------------
       
   568 //  
       
   569 void CBTRCCLinker::TState::DoCancel()
       
   570     {
       
   571     TRACE_INFO((_L("TState::DoCancel #Default# state %d"), iParent.iCurrentStateIndex))
       
   572     }
       
   573 
       
   574 // -----------------------------------------------------------------------------
       
   575 // CBTRCCLinker::TState::Connect
       
   576 // -----------------------------------------------------------------------------
       
   577 //  
       
   578 void CBTRCCLinker::TState::Connect(const TBTDevAddr& /*aAddr*/, TRequestStatus& aStatus)
       
   579     {
       
   580     TRACE_INFO((_L("TState::Connect #Default# state %d"), iParent.iCurrentStateIndex))
       
   581     TRequestStatus* status = &aStatus;
       
   582     aStatus = KRequestPending;
       
   583     User::RequestComplete(status, KErrInUse);
       
   584     }
       
   585 
       
   586 // -----------------------------------------------------------------------------
       
   587 // CBTRCCLinker::TState::CancelConnect
       
   588 // -----------------------------------------------------------------------------
       
   589 //  
       
   590 void CBTRCCLinker::TState::CancelConnect(const TBTDevAddr& /*aAddr*/)
       
   591     {
       
   592     TRACE_INFO((_L("TState::CancelConnect #Default# state %d"), iParent.iCurrentStateIndex))
       
   593     }
       
   594 
       
   595 // -----------------------------------------------------------------------------
       
   596 // CBTRCCLinker::TState::Disconnect
       
   597 // -----------------------------------------------------------------------------
       
   598 //  
       
   599 void CBTRCCLinker::TState::Disconnect(TRequestStatus& aStatus, const TBTDevAddr& /*aAddr*/)
       
   600     {
       
   601     TRACE_INFO((_L("TState::Disconnect #Default# state %d"), iParent.iCurrentStateIndex))
       
   602     // We assume disconnect is always succeeded and complete this request immediately,
       
   603     // because a) disconnect is not able to be cancelled, and
       
   604     //         b) we can do nothing if disconnect fails
       
   605     TRequestStatus* status = &aStatus;
       
   606     aStatus = KRequestPending;
       
   607     User::RequestComplete(status, KErrNone);
       
   608     }
       
   609 
       
   610 // -----------------------------------------------------------------------------
       
   611 // CBTRCCLinker::TState::RemConRequestCompleted
       
   612 // -----------------------------------------------------------------------------
       
   613 //  
       
   614 void CBTRCCLinker::TState::RemConRequestCompleted(TInt /*aErr*/)
       
   615     {
       
   616     TRACE_INFO((_L("TState::RemConRequestCompleted #Default# state %d"), iParent.iCurrentStateIndex))
       
   617     }
       
   618 
       
   619 // -----------------------------------------------------------------------------
       
   620 // CBTRCCLinker::TState::UpdateRemoteVolumeControling
       
   621 // -----------------------------------------------------------------------------
       
   622 //  
       
   623 void CBTRCCLinker::TState::UpdateRemoteVolumeControling(TBool /*aActivated*/)
       
   624     {
       
   625     TRACE_INFO((_L("TState::UpdateRemoteVolumeControling #Default# state %d"), iParent.iCurrentStateIndex))
       
   626     }
       
   627 
       
   628 // ================= TStateIdle MEMBER FUNCTIONS =======================
       
   629 
       
   630 // -----------------------------------------------------------------------------
       
   631 // CBTRCCLinker::TStateIdle::TStateIdle
       
   632 // -----------------------------------------------------------------------------
       
   633 //
       
   634 CBTRCCLinker::TStateIdle::TStateIdle(CBTRCCLinker& aParent)
       
   635     : TState(aParent)
       
   636     {
       
   637     }
       
   638 
       
   639 // -----------------------------------------------------------------------------
       
   640 // CBTRCCLinker::TStateIdle::Enter
       
   641 // -----------------------------------------------------------------------------
       
   642 //
       
   643 void CBTRCCLinker::TStateIdle::Enter()
       
   644     {
       
   645     TRACE_FUNC
       
   646     iParent.iRemoteAddr = TBTDevAddr();
       
   647     iParent.DoSubscribeConnetionStatus();
       
   648     iParent.ResetVolmeControlSetting();
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // CBTRCCLinker::TStateIdle::DoCancel
       
   653 // -----------------------------------------------------------------------------
       
   654 //
       
   655 void CBTRCCLinker::TStateIdle::DoCancel()
       
   656     {
       
   657     TRACE_FUNC
       
   658     iParent.iInterfaceSelector->NotifyConnectionsChangeCancel();
       
   659     }
       
   660 
       
   661 // -----------------------------------------------------------------------------
       
   662 // CBTRCCLinker::TStateIdle::Connect
       
   663 // -----------------------------------------------------------------------------
       
   664 //
       
   665 void CBTRCCLinker::TStateIdle::Connect(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
       
   666     {
       
   667     TRACE_FUNC
       
   668     iParent.iRemoteAddr = aAddr;
       
   669     aStatus = KRequestPending;
       
   670     iParent.iClientRequest = &aStatus;
       
   671     iParent.DoCancelSubscribe();
       
   672     iParent.ChangeState(EStateIndexConnecting);
       
   673     }
       
   674 
       
   675 // -----------------------------------------------------------------------------
       
   676 // CBTRCCLinker::TStateIdle::RemConRequestCompleted
       
   677 // -----------------------------------------------------------------------------
       
   678 //
       
   679 void CBTRCCLinker::TStateIdle::RemConRequestCompleted(TInt aErr)
       
   680     {
       
   681     TRACE_FUNC
       
   682     if (!aErr)
       
   683         {
       
   684         RArray<TBTDevAddr> connects;
       
   685         iParent.DoGetRemConConnectionStatus(connects);
       
   686         
       
   687         // There can only be maximum one AVRCP connection at this time, as BTRCC is running 
       
   688         // as long as BT is ON. 
       
   689         if (connects.Count())
       
   690             {
       
   691             iParent.iRemoteAddr = connects[0];
       
   692             if (iParent.iAccObserver.IsAvrcpVolCTSupported())
       
   693                 {
       
   694                 iParent.DoRemConOrientation();
       
   695                 }
       
   696             iParent.ChangeState(EStateIndexConnected);
       
   697             // This function call is safe after state transition because the state machine
       
   698             // keeps all state instances in memory.
       
   699             // AVRCP Controller initiates connection with AVRCP Traget. Thus we assume the remote
       
   700             // is a CT.
       
   701             iParent.AccObserver().NewAccessory(iParent.iRemoteAddr, ERemConCT);
       
   702             }
       
   703         else
       
   704             {
       
   705             // Remain in this state, re-subsrcibe
       
   706             iParent.DoSubscribeConnetionStatus();
       
   707             }
       
   708         connects.Close();
       
   709         }
       
   710     else if (aErr != KErrServerTerminated)
       
   711         {
       
   712         // some error returned in subscribe, redo if the reason is other than server termination.
       
   713         iParent.DoSubscribeConnetionStatus();
       
   714         }
       
   715     }
       
   716 
       
   717 // -----------------------------------------------------------------------------
       
   718 // CBTRCCLinker::TStateConnecting::TStateConnecting
       
   719 // -----------------------------------------------------------------------------
       
   720 //
       
   721 CBTRCCLinker::TStateConnecting::TStateConnecting(CBTRCCLinker& aParent)
       
   722     : TState(aParent)
       
   723     {
       
   724     }
       
   725 
       
   726 // -----------------------------------------------------------------------------
       
   727 // CBTRCCLinker::TStateConnecting::Enter
       
   728 // -----------------------------------------------------------------------------
       
   729 //
       
   730 void CBTRCCLinker::TStateConnecting::Enter()
       
   731     {
       
   732     TRACE_FUNC
       
   733     iConnectCanceled = EFalse;
       
   734     iParent.DoConnect();
       
   735     }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // CBTRCCLinker::TStateConnecting::DoCancel
       
   739 // -----------------------------------------------------------------------------
       
   740 //
       
   741 void CBTRCCLinker::TStateConnecting::DoCancel()
       
   742     {
       
   743     TRACE_FUNC
       
   744     iParent.iInterfaceSelector->ConnectBearerCancel();
       
   745     }
       
   746 
       
   747 // -----------------------------------------------------------------------------
       
   748 // CBTRCCLinker::TStateConnecting::CancelConnect
       
   749 // -----------------------------------------------------------------------------
       
   750 //
       
   751 void CBTRCCLinker::TStateConnecting::CancelConnect(const TBTDevAddr& aAddr)
       
   752     {
       
   753     TRACE_INFO(_L("TStateConnecting::CancelConnect"))
       
   754     if (aAddr == iParent.iRemoteAddr)
       
   755         {
       
   756         // RemCon FW doesn't bring down AVRCP linking in ConnectBearerCancel(), so
       
   757         // we set the flag which will be checked when the completion of connecting request.
       
   758         iConnectCanceled = ETrue;
       
   759         if (iParent.iClientRequest)
       
   760             User::RequestComplete(iParent.iClientRequest, KErrCancel);
       
   761         }
       
   762     }
       
   763 
       
   764 // -----------------------------------------------------------------------------
       
   765 // CBTRCCLinker::TStateConnecting::RemConRequestCompleted
       
   766 // -----------------------------------------------------------------------------
       
   767 //
       
   768 void CBTRCCLinker::TStateConnecting::RemConRequestCompleted(TInt aErr)
       
   769     {
       
   770     TRACE_FUNC
       
   771     TBTRCCStateIndex nextState = (aErr) ? EStateIndexIdle : EStateIndexConnected;
       
   772     if (!aErr && iConnectCanceled)
       
   773         {
       
   774         nextState =  EStateIndexDisconnect;
       
   775         aErr = KErrCancel;
       
   776         }
       
   777     if (iParent.iClientRequest)
       
   778         User::RequestComplete(iParent.iClientRequest, aErr);
       
   779     iParent.ChangeState(nextState);
       
   780     }
       
   781 
       
   782 // ================= TStateConnected MEMBER FUNCTIONS =======================
       
   783 
       
   784 // -----------------------------------------------------------------------------
       
   785 // CBTRCCLinker::TStateConnected::TStateConnected
       
   786 // -----------------------------------------------------------------------------
       
   787 //
       
   788 CBTRCCLinker::TStateConnected::TStateConnected(CBTRCCLinker& aParent)
       
   789     : TState(aParent)
       
   790     {
       
   791     }
       
   792 
       
   793 // -----------------------------------------------------------------------------
       
   794 // CBTRCCLinker::TStateConnected::Enter
       
   795 // -----------------------------------------------------------------------------
       
   796 //
       
   797 void CBTRCCLinker::TStateConnected::Enter()
       
   798     {
       
   799     TRACE_FUNC
       
   800     iParent.DoSubscribeConnetionStatus();
       
   801     if (iParent.iRvcActivated)
       
   802         {
       
   803         iParent.StartRemoteVolumeControl();
       
   804         }
       
   805     }
       
   806 
       
   807 // -----------------------------------------------------------------------------
       
   808 // CBTRCCLinker::TStateConnected::DoCancel
       
   809 // -----------------------------------------------------------------------------
       
   810 //
       
   811 void CBTRCCLinker::TStateConnected::DoCancel()
       
   812     {
       
   813     TRACE_FUNC
       
   814     iParent.iInterfaceSelector->NotifyConnectionsChangeCancel();
       
   815     }
       
   816 
       
   817 // -----------------------------------------------------------------------------
       
   818 // CBTRCCLinker::TStateConnected::Connect
       
   819 // -----------------------------------------------------------------------------
       
   820 //
       
   821 void CBTRCCLinker::TStateConnected::Connect(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
       
   822     {
       
   823     TRACE_FUNC
       
   824     TInt err = KErrNone;
       
   825     if (iParent.iRemoteAddr != aAddr)
       
   826         {
       
   827         err = KErrInUse;
       
   828         }
       
   829     TRequestStatus* status = &aStatus;
       
   830     aStatus = KRequestPending;
       
   831     User::RequestComplete(status, err);
       
   832     }
       
   833 
       
   834 // -----------------------------------------------------------------------------
       
   835 // CBTRCCLinker::TStateConnected::Disconnect
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 void CBTRCCLinker::TStateConnected::Disconnect(TRequestStatus& aStatus, const TBTDevAddr& aAddr)
       
   839     {
       
   840     TRACE_FUNC
       
   841     TState::Disconnect(aStatus, aAddr);
       
   842     if (iParent.iRemoteAddr == aAddr)
       
   843         {
       
   844         iParent.DoCancelSubscribe();
       
   845    	    iParent.StopRemoteVolumeControl();
       
   846     	iParent.ChangeState(EStateIndexDisconnect);
       
   847         }
       
   848     }
       
   849 
       
   850 // -----------------------------------------------------------------------------
       
   851 // Find
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 TBool Find(const RArray<TBTDevAddr>& aList, const TBTDevAddr& aAddr)
       
   855     {
       
   856     TInt count = aList.Count();
       
   857     for (TInt i = 0; i < count; i++)
       
   858         {
       
   859         if (aList[i] == aAddr)
       
   860             {
       
   861             return ETrue;
       
   862             }
       
   863         }
       
   864     return EFalse;
       
   865     }
       
   866 
       
   867 // -----------------------------------------------------------------------------
       
   868 // CBTRCCLinker::TStateConnected::RemConRequestCompleted
       
   869 // -----------------------------------------------------------------------------
       
   870 //    
       
   871 void CBTRCCLinker::TStateConnected::RemConRequestCompleted(TInt aErr)
       
   872     {
       
   873     TRACE_FUNC
       
   874     if (!aErr)
       
   875         {
       
   876         RArray<TBTDevAddr> connects;
       
   877         iParent.DoGetRemConConnectionStatus(connects);
       
   878         
       
   879         // There might be more than one AVRCP connections at this time, 
       
   880         // We only check if the connection maintained by BTRCC exists or not.
       
   881         // For connection with other devices, we are not interested since currently
       
   882         // BT audio design only allows single HFP/A2DP/AVRCP connection.
       
   883         if (!Find(connects, iParent.iRemoteAddr))
       
   884             {
       
   885             iParent.AccObserver().AccessoryDisconnected(iParent.iRemoteAddr, EAnyRemConProfiles);
       
   886             iParent.StopRemoteVolumeControl();
       
   887             iParent.ChangeState(EStateIndexIdle);
       
   888             }
       
   889         else 
       
   890             {
       
   891             // not interested connection status change, remain in this state and re-subscribe
       
   892             iParent.DoSubscribeConnetionStatus();
       
   893             }
       
   894         connects.Close();
       
   895         }
       
   896     else if (aErr == KErrServerTerminated || aErr == KErrCommsBreak)
       
   897         {
       
   898         // Serious error, requires a restart. 
       
   899         // ToDo: Check and possibly redesign the connection/disconnection
       
   900         // To enable it from this class.
       
   901 
       
   902         // Must at least inform the parent that there was a disconnection, 
       
   903         // Or should we just connect back silently?
       
   904 
       
   905         // iRemoteAddr stores the address so this is possible in theory. 
       
   906         }
       
   907     else 
       
   908         {
       
   909         // Other error, subscribe again. 
       
   910         iParent.DoSubscribeConnetionStatus();
       
   911         }
       
   912     }
       
   913 
       
   914 // -----------------------------------------------------------------------------
       
   915 // CBTRCCLinker::TStateConnected::UpdateRemoteVolumeControling
       
   916 // -----------------------------------------------------------------------------
       
   917 //    
       
   918 void CBTRCCLinker::TStateConnected::UpdateRemoteVolumeControling(TBool aActivated)
       
   919     {
       
   920     TRACE_FUNC
       
   921     if (aActivated)
       
   922         {
       
   923         iParent.StartRemoteVolumeControl();
       
   924         }
       
   925     else
       
   926         {
       
   927         iParent.StopRemoteVolumeControl();
       
   928         }    
       
   929     }
       
   930 
       
   931 
       
   932 // ================= TStateDisconnect MEMBER FUNCTIONS =======================
       
   933 
       
   934 // -----------------------------------------------------------------------------
       
   935 // CBTRCCLinker::TStateDisconnect::TStateDisconnect
       
   936 // -----------------------------------------------------------------------------
       
   937 //
       
   938 CBTRCCLinker::TStateDisconnect::TStateDisconnect(CBTRCCLinker& aParent)
       
   939     : TState(aParent)
       
   940     {
       
   941     }
       
   942 
       
   943 // -----------------------------------------------------------------------------
       
   944 // CBTRCCLinker::TStateDisconnect::Enter
       
   945 // -----------------------------------------------------------------------------
       
   946 //
       
   947 void CBTRCCLinker::TStateDisconnect::Enter()
       
   948     {
       
   949     TRACE_FUNC
       
   950     iParent.DoDisconnect();
       
   951     }
       
   952     
       
   953 // -----------------------------------------------------------------------------
       
   954 // CBTRCCLinker::TStateDisconnect::DoCancel
       
   955 // -----------------------------------------------------------------------------
       
   956 //
       
   957 void CBTRCCLinker::TStateDisconnect::DoCancel()
       
   958     {
       
   959     TRACE_FUNC
       
   960     if (iParent.iAccObserver.IsAvrcpVolCTSupported())
       
   961         {    
       
   962         iParent.iInterfaceSelector->DisconnectBearerCancel();
       
   963         }
       
   964     else
       
   965         {
       
   966         iParent.iInterfaceSelectorForDisconnectingTargetSession->DisconnectBearerCancel();
       
   967         }
       
   968     }
       
   969 
       
   970 // -----------------------------------------------------------------------------
       
   971 // CBTRCCLinker::TStateDisconnect::RemConRequestCompleted
       
   972 // -----------------------------------------------------------------------------
       
   973 //
       
   974 void CBTRCCLinker::TStateDisconnect::RemConRequestCompleted(TInt /*aErr*/)
       
   975     {
       
   976     TRACE_FUNC
       
   977     iParent.ChangeState(EStateIndexIdle);
       
   978     }
       
   979 
       
   980 //  End of File