bluetoothengine/btaudioman/src/basrvaccman.cpp
changeset 0 f63038272f30
child 2 0b192a3a05a4
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:  Implementation of an accessory management.
       
    15 *  Version     : %version:  14.1.7 %
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <centralrepository.h>
       
    22 #include "basrvaccman.h"
       
    23 #include "BTAccSession.h"
       
    24 #include "BTAccClientSrv.h"
       
    25 #include "basrvacc.h"
       
    26 #include "BTAccInfo.h"
       
    27 #include "basrvpluginman.h"
       
    28 #include "BTAccFwIf.h"
       
    29 #include "debug.h"
       
    30 
       
    31 const TInt KOpenAudioListenerId = 20;
       
    32 const TInt KCloseAudioListenerId = 21;
       
    33 const TInt KShowNoteRequest = 22;
       
    34 const TInt KAsyncHandlingRequest = 23;
       
    35 
       
    36 // ================= MEMBER FUNCTIONS =======================
       
    37 
       
    38 CBasrvAccMan* CBasrvAccMan::NewL()
       
    39     {
       
    40     CBasrvAccMan* self = new (ELeave) CBasrvAccMan();
       
    41     CleanupStack::PushL(self);
       
    42     self->ConstructL();
       
    43     CleanupStack::Pop(self);
       
    44     return self;
       
    45     }
       
    46 
       
    47 CBasrvAccMan::~CBasrvAccMan()
       
    48     {
       
    49     delete iOpenListener;
       
    50     delete iCloseListener;
       
    51     delete iAsyncHandlingActive;
       
    52     
       
    53     // Response to any buffered audio request from Audio Policy.
       
    54     if (iAccfw)
       
    55         {
       
    56         TInt count = iAudioRequests.Count();
       
    57         for (TInt i = 0;  i < count; i++)
       
    58             {
       
    59             if (iAudioRequests[i].iReqType == EOpenReqFromAudioPolicy)
       
    60                 {
       
    61                 TRAP_IGNORE(iAccfw->AudioConnectionOpenCompleteL(
       
    62                     iAudioRequests[i].iAddr, KErrDisconnected));
       
    63                 }
       
    64             else if (iAudioRequests[i].iReqType == ECloseReqFromAudioPolicy)
       
    65                 {
       
    66                 TRAP_IGNORE(iAccfw->AudioConnectionCloseCompleteL(
       
    67                     iAudioRequests[i].iAddr, KErrDisconnected));
       
    68                 }
       
    69             }
       
    70         }
       
    71     
       
    72     iAudioRequests.Close();
       
    73     iAccs.ResetAndDestroy();
       
    74     iAccs.Close();
       
    75     delete iAccfw;
       
    76     delete iPluginMan;
       
    77     iNotifierArray.ResetAndDestroy();
       
    78     iNotifierArray.Close();
       
    79     iClientRequests.Close();
       
    80     DestructVariant();
       
    81     TRACE_FUNC    
       
    82     }
       
    83 
       
    84 void CBasrvAccMan::LoadServicesL()
       
    85     {
       
    86     TRACE_FUNC    
       
    87     if (!iPluginMan)
       
    88         {
       
    89         iPluginMan = CBasrvPluginMan::NewL();
       
    90         }
       
    91     iPluginMan->LoadPluginsL(*this);
       
    92     }
       
    93     
       
    94 void CBasrvAccMan::ConnectL(CBTAccSession& aSession, const TBTDevAddr& aAddr)
       
    95     {
       
    96     TRACE_FUNC
       
    97     TClientRequestCache request;
       
    98     request.iSession = &aSession;
       
    99     request.iRequest = EBTAccSrvConnectToAccessory;
       
   100     request.iAddr = aAddr;
       
   101     iClientRequests.AppendL(request);
       
   102     
       
   103     //remove the last item from the RArray if a leave occurs later
       
   104     TCleanupItem cleanupItem(CleanupLastItemFromClientRequestsArray, &iClientRequests);
       
   105     CleanupStack::PushL(cleanupItem);
       
   106     
       
   107     TInt idx = FindAcc(aAddr);
       
   108     if (idx >= 0)
       
   109         {
       
   110         iAccs[idx]->ConnectL(aAddr);
       
   111         }
       
   112     else
       
   113         {
       
   114         CBasrvAcc* acc = CBasrvAcc::NewLC(*this);
       
   115         iAccs.AppendL(acc);
       
   116         CleanupStack::Pop(acc);
       
   117         acc->ConnectL(aAddr);
       
   118         }
       
   119     
       
   120     CleanupStack::Pop(&iClientRequests);
       
   121     }
       
   122 
       
   123 void CBasrvAccMan::CancelConnect(const TBTDevAddr& aAddr)
       
   124     {
       
   125     TRACE_FUNC
       
   126     TInt idx = FindAcc(aAddr);
       
   127     if (idx >= 0)
       
   128         {
       
   129 	    TInt count = iClientRequests.Count();
       
   130 	    for (TInt i = 0; i < count; i++)
       
   131 	        {
       
   132 	        if (iClientRequests[i].iAddr == aAddr && 
       
   133 	            iClientRequests[i].iRequest == EBTAccSrvConnectToAccessory)
       
   134 	            {
       
   135 	            iClientRequests.Remove(i);
       
   136 	            break;
       
   137 	            }
       
   138 	        }        
       
   139         iAccs[idx]->CancelConnect();
       
   140         }
       
   141     }
       
   142 
       
   143 void CBasrvAccMan::DisconnectL(CBTAccSession& aSession, const TBTDevAddr& aAddr)
       
   144     {
       
   145     TRACE_FUNC
       
   146     TInt idx = FindAcc(aAddr);
       
   147     if (idx >= 0)
       
   148         {
       
   149         RemoveAudioRequest(aAddr);
       
   150         TClientRequestCache request;
       
   151         request.iSession = &aSession;
       
   152         request.iRequest = EBTAccSrvDisconnectAccessory;
       
   153         request.iAddr = aAddr;
       
   154         iClientRequests.AppendL(request);
       
   155         iAccs[idx]->DisconnectL();
       
   156         }
       
   157     else
       
   158         {
       
   159         aSession.DisconnectCompleted(EAnyMonoAudioProfiles, KErrNotFound);
       
   160         }
       
   161     }
       
   162 
       
   163 void CBasrvAccMan::DisconnectAllL(CBTAccSession& aSession)
       
   164     {
       
   165     TRACE_FUNC
       
   166     if (!iDisconnectAllPending)
       
   167         {
       
   168         TInt count = iAccs.Count();
       
   169         if (!count)
       
   170             {
       
   171             aSession.DisconnectAllCompleted(KErrNone);
       
   172             }
       
   173         else
       
   174             {
       
   175             iSessionOfDisconnectAll = &aSession;
       
   176             for (TInt i = 0; i < count; i++)
       
   177                 {
       
   178                 RemoveAudioRequest(iAccs[i]->Remote());
       
   179                 iAccs[i]->DisconnectL();
       
   180                 }
       
   181             iDisconnectAllPending = ETrue;
       
   182             }
       
   183         }
       
   184     }
       
   185 
       
   186 void CBasrvAccMan::SetProfileNotifySession(CBTAccSession& aSession)
       
   187     {
       
   188     iProfileNotifySession = &aSession;
       
   189     }
       
   190 
       
   191 void CBasrvAccMan::ClearProfileNotifySession(CBTAccSession& aSession)
       
   192     {
       
   193     //if the session passed in is equal to what we have stored
       
   194     if (&aSession == iProfileNotifySession)
       
   195         {
       
   196         //invalidate the pointer to the session
       
   197         iProfileNotifySession = NULL;
       
   198         }
       
   199     }
       
   200 
       
   201 const TAccInfo* CBasrvAccMan::AccInfo(const TBTDevAddr& aAddr)
       
   202     {
       
   203     TInt count = iAccs.Count();
       
   204     const TAccInfo* info = NULL;
       
   205     for (TInt i = 0; i < count; i++)
       
   206         {
       
   207         info = iAccs[i]->AccInfo(aAddr);
       
   208         if (info)
       
   209             {
       
   210             return info;
       
   211             }
       
   212         }
       
   213     return NULL;
       
   214     }
       
   215 
       
   216 CBasrvPluginMan& CBasrvAccMan::PluginMan()
       
   217     {
       
   218     return *iPluginMan;
       
   219     }
       
   220     
       
   221 void CBasrvAccMan::ConnectCompletedL(const TBTDevAddr& aAddr, TInt aErr, 
       
   222     TInt aProfile, const RArray<TBTDevAddr>* aConflicts)
       
   223     {
       
   224     TRACE_FUNC
       
   225     TInt count = iClientRequests.Count();
       
   226     for (TInt i = 0; i < count; i++)
       
   227         {
       
   228         if (iClientRequests[i].iAddr == aAddr && 
       
   229             iClientRequests[i].iRequest == EBTAccSrvConnectToAccessory)
       
   230             {
       
   231             iClientRequests[i].iSession->ConnectCompleted(aErr, aProfile, aConflicts);
       
   232             iClientRequests.Remove(i);
       
   233             break;
       
   234             }
       
   235         }
       
   236     }
       
   237     
       
   238 void CBasrvAccMan::DisconnectCompletedL(const TBTDevAddr& aAddr, TInt aProfile, TInt aErr)
       
   239     {
       
   240     TRACE_FUNC
       
   241     TInt count = iClientRequests.Count();
       
   242     for (TInt i = 0; i < count; i++)
       
   243         {
       
   244         if (iClientRequests[i].iAddr == aAddr && 
       
   245             iClientRequests[i].iRequest == EBTAccSrvDisconnectAccessory)
       
   246             {
       
   247             iClientRequests[i].iSession->DisconnectCompleted(aProfile, aErr);
       
   248             iClientRequests.Remove(i);
       
   249             break;
       
   250             }
       
   251         }
       
   252     }
       
   253 
       
   254 #define TRACE_AUDIO_REQUEST_COMPLETE \
       
   255     TRACE_INFO_SEG(\
       
   256         {\
       
   257         TBuf<12> buf;\
       
   258         aAddr.GetReadable(buf);\
       
   259         Trace(_L("[Audio Request Complete] %d %d at '%S', err %d"), \
       
   260             iAudioRequests[0].iReqType, aType, &buf, aErr);\
       
   261         });
       
   262 
       
   263 TInt CBasrvAccMan::OpenAudioCompleted(const TBTDevAddr& aAddr, TAccAudioType aType, TInt aErr)
       
   264     {
       
   265     TInt err = KErrNone;
       
   266     if (iAudioRequests.Count())
       
   267         {
       
   268         TRACE_AUDIO_REQUEST_COMPLETE
       
   269         TRequestType reqType = iAudioRequests[0].iReqType;
       
   270         iAudioRequests.Remove(0);
       
   271         TInt latency = iPluginMan->AudioLinkLatency();
       
   272         if (reqType == EOpenReqFromAudioPolicy)
       
   273             {
       
   274             	
       
   275 	        TRAP(err, AccfwConnectionL()->AudioConnectionOpenCompleteL(aAddr, aErr, latency))
       
   276 	        TRACE_INFO((_L("AccfwConnectionL()->AudioConnectionOpenCompleteL trap %d"), err))
       
   277 	        if (!err && !aErr)
       
   278 	            {
       
   279 	            err = NotifyAccFwAudioOpened(aAddr, aType, latency);
       
   280 	            }
       
   281            else if (err == KErrAlreadyExists && !aErr)
       
   282                 {
       
   283         	    RejectAudioLink(aAddr, aType);
       
   284                 }
       
   285            }
       
   286         }
       
   287     if (!err) // if err, a rejecting audio link has been scheduled.
       
   288 	    {
       
   289 	    TRAP_IGNORE(DoAudioRequestL());
       
   290 	    }
       
   291     return err;
       
   292     }
       
   293     
       
   294 TInt CBasrvAccMan::CloseAudioCompleted(const TBTDevAddr& aAddr, TAccAudioType aType, TInt aErr)
       
   295     {
       
   296     TInt err = KErrNone;
       
   297     if (iAudioRequests.Count())
       
   298         {
       
   299         TRACE_AUDIO_REQUEST_COMPLETE
       
   300         if (iAudioRequests[0].iReqType == ECloseReqFromAudioPolicy)
       
   301             {
       
   302             TRAP(err, AccfwConnectionL()->NotifyAudioLinkCloseL(aAddr, aType));
       
   303             TRACE_INFO((_L("AccfwConnectionL()->NotifyAudioLinkCloseL trap %d"), err))
       
   304             TRAP(err, AccfwConnectionL()->AudioConnectionCloseCompleteL(aAddr, aErr));
       
   305             TRACE_INFO((_L("AccfwConnectionL()->AudioConnectionCloseCompleteL trap %d"), err))
       
   306             }
       
   307         iAudioRequests.Remove(0);
       
   308         }
       
   309     if (iAudioRequests.Count())
       
   310         {
       
   311         TRAP_IGNORE(DoAudioRequestL());
       
   312         }
       
   313     return err;
       
   314     }
       
   315 
       
   316 void CBasrvAccMan::AccObsoleted(CBasrvAcc* aAcc, const TBTDevAddr& /*aAddr*/)
       
   317     {
       
   318     TRACE_FUNC
       
   319     TInt idx = iAccs.Find(aAcc);
       
   320     if (idx >= 0)
       
   321         {
       
   322         RemoveAudioRequest(iAccs[idx]->Remote());
       
   323         delete aAcc;
       
   324         iAccs.Remove(idx);
       
   325         }
       
   326     if (!iAccs.Count())
       
   327         {
       
   328         delete iOpenListener;
       
   329         iOpenListener = NULL;
       
   330         delete iCloseListener;
       
   331         iCloseListener = NULL;
       
   332         delete iAccfw;
       
   333         iAccfw = NULL;
       
   334         iAudioRequests.Reset();
       
   335         if (iDisconnectAllPending)
       
   336             {
       
   337             iDisconnectAllPending = EFalse;
       
   338             if (iSessionOfDisconnectAll)
       
   339                 iSessionOfDisconnectAll->DisconnectAllCompleted(KErrNone);
       
   340             }
       
   341         }
       
   342     }
       
   343     
       
   344 CBasrvAccfwIf* CBasrvAccMan::AccfwConnectionL(const TAccInfo* aInfo)
       
   345     {
       
   346     if (!iAccfw)
       
   347         {
       
   348         iAccfw = CBasrvAccfwIf::NewL(aInfo);
       
   349         }
       
   350     return iAccfw;
       
   351     }
       
   352 
       
   353 CBasrvAccfwIf* CBasrvAccMan::NewAccfwConnectionInstanceL()
       
   354     {
       
   355     TRACE_FUNC
       
   356     return CBasrvAccfwIf::NewL(NULL);
       
   357     }
       
   358     
       
   359 void CBasrvAccMan::ListenAudioRequestL()
       
   360     {
       
   361     TRACE_FUNC
       
   362     if (!iOpenListener)
       
   363         {
       
   364         iCloseListener = CBasrvActive::NewL(*this, CActive::EPriorityStandard, KCloseAudioListenerId);
       
   365         iOpenListener = CBasrvActive::NewL(*this, CActive::EPriorityStandard, KOpenAudioListenerId);
       
   366         AccfwConnectionL()->NotifyBTAudioLinkOpenReq(iOpenAddr,iOpenListener->iStatus, iOpenType);
       
   367         iOpenListener->GoActive();
       
   368         AccfwConnectionL()->NotifyBTAudioLinkCloseReq(iCloseAddr,iCloseListener->iStatus, iCloseType);
       
   369         iCloseListener->GoActive();
       
   370         }
       
   371     }
       
   372 
       
   373 void CBasrvAccMan::CancelAudioRequestListen()
       
   374     {
       
   375     delete iOpenListener;
       
   376     iOpenListener = NULL;
       
   377     delete iCloseListener;
       
   378     iCloseListener = NULL;
       
   379     TRACE_FUNC
       
   380     }
       
   381 
       
   382 void CBasrvAccMan::RemoveAudioRequest(const TBTDevAddr& aAddr)
       
   383     {
       
   384     TRACE_FUNC
       
   385     TInt count = iAudioRequests.Count();
       
   386     TInt i = 0;
       
   387     while(count && i < count)
       
   388         {
       
   389         if (iAudioRequests[i].iAddr == aAddr)
       
   390             {
       
   391             TRACE_INFO_SEG(
       
   392                 {
       
   393                 TBuf<12> buf;
       
   394                 aAddr.GetReadable(buf);
       
   395                 Trace(_L("[Audio Request Aborted] %d %d at '%S'"), 
       
   396                     iAudioRequests[i].iReqType, iAudioRequests[i].iAudioType, &buf);
       
   397                 });
       
   398             if (iAudioRequests[i].iReqType == EOpenReqFromAudioPolicy)
       
   399                 {
       
   400                 TRAP_IGNORE(AccfwConnectionL()->AudioConnectionOpenCompleteL(aAddr, KErrDisconnected));
       
   401                 }
       
   402             else if (iAudioRequests[i].iReqType == ECloseReqFromAudioPolicy)
       
   403                 {
       
   404                 TRAP_IGNORE(AccfwConnectionL()->AudioConnectionCloseCompleteL(aAddr, KErrDisconnected));
       
   405                 }
       
   406             iAudioRequests.Remove(i);
       
   407             count--;
       
   408             }
       
   409         else
       
   410             {
       
   411             i++;
       
   412             }
       
   413         }
       
   414     }
       
   415 
       
   416 void CBasrvAccMan::ShowNote(TBTGenericInfoNoteType aNote, const TBTDevAddr& aAddr)
       
   417     {
       
   418     TRACE_INFO((_L("CBasrvAccMan::ShowNote %d"), aNote))
       
   419     TRAPD(err, iNotifierArray.Append(CBasrvActiveNotifier::NewL(*this, CActive::EPriorityStandard, KShowNoteRequest, aAddr, aNote)));
       
   420     if (err)
       
   421         {
       
   422         TRACE_ERROR((_L("could not construct active notifer object")))
       
   423         return;
       
   424         }
       
   425     }
       
   426 
       
   427 void CBasrvAccMan::FilterProfileSupport(TAccInfo& aInfo)
       
   428     {
       
   429     TInt pluginbit = iPluginMan->AvailablePlugins();
       
   430     aInfo.iSuppProfiles &= pluginbit;
       
   431     }
       
   432 
       
   433 TInt CBasrvAccMan::NotifyAccFwAudioOpened(const TBTDevAddr& aAddr, TAccAudioType aType, TInt /*aLatency*/)
       
   434     {
       
   435     TRAPD(err, AccfwConnectionL()->NotifyAudioLinkOpenL(aAddr, aType));
       
   436     TRACE_INFO((_L("AccfwConnectionL()->NotifyAudioLinkOpenL type %d trap %d"), aType, err))
       
   437     if (err)
       
   438         {
       
   439         RejectAudioLink(aAddr, aType);
       
   440         }
       
   441     return err;
       
   442     }
       
   443 
       
   444 TInt CBasrvAccMan::AccInfos(RPointerArray<const TAccInfo>& aInfos)
       
   445     {
       
   446     TInt count = iAccs.Count();
       
   447     TInt err = KErrNone;
       
   448     
       
   449     for (TInt i = 0; i < count; i++)
       
   450         {
       
   451         err = aInfos.Append(&(iAccs[i]->AccInfo()));
       
   452         
       
   453         if (err != KErrNone)
       
   454             {
       
   455             //an error occured so cleanup
       
   456             aInfos.Close();
       
   457             break;
       
   458             }
       
   459         }
       
   460     
       
   461     return err;
       
   462     }
       
   463 
       
   464 void CBasrvAccMan::NotifyClientNewProfile(TInt aProfile, const TBTDevAddr& aAddr)
       
   465     {
       
   466     if (iProfileNotifySession)
       
   467         {
       
   468         iProfileNotifySession->NotifyClientNewProfile(aProfile, aAddr);
       
   469         }
       
   470     }
       
   471     
       
   472 void CBasrvAccMan::NotifyClientNoProfile(TInt aProfile, const TBTDevAddr& aAddr)
       
   473     {
       
   474     if (iProfileNotifySession)
       
   475         {
       
   476         iProfileNotifySession->NotifyClientNoProfile(aProfile, aAddr);
       
   477         }
       
   478     }
       
   479 
       
   480 TBTEngConnectionStatus CBasrvAccMan::ConnectionStatus4Client(const TBTDevAddr& aAddr) const
       
   481     {
       
   482     TInt count = iAccs.Count();
       
   483     for (TInt i = 0; i < count; i++)
       
   484         {
       
   485         if (iAccs[i]->Remote() == aAddr)
       
   486             {
       
   487             return iAccs[i]->ConnectionStatus();
       
   488             }
       
   489         }
       
   490     return EBTEngNotConnected;
       
   491     }
       
   492 
       
   493 TBool CBasrvAccMan::IsAvrcpVolCTSupported()
       
   494     {
       
   495     return iAvrcpVolCTSupported;
       
   496     }
       
   497     
       
   498 TBool CBasrvAccMan::IsAbsoluteVolumeSupported(const TBTDevAddr& aAddr)
       
   499 	{
       
   500     TInt count = iAccs.Count();
       
   501     for (TInt i = 0; i < count; i++)
       
   502         {
       
   503         if (iAccs[i]->Remote() == aAddr)
       
   504             {
       
   505             TBool ret = iAccs[i]->AccInfo().iAvrcpVersion == TAccInfo::EAvrcpVersion14 ? ETrue : EFalse; 
       
   506             return ret;
       
   507             }
       
   508         }
       
   509     return EFalse;
       
   510 	}
       
   511     
       
   512 TBool CBasrvAccMan::DisconnectIfAudioOpenFails()
       
   513     {
       
   514     return iDisconnectIfAudioOpenFails;
       
   515     }
       
   516     
       
   517 void CBasrvAccMan::NewAccessory( const TBTDevAddr& aAddr, TProfiles aProfile )
       
   518     {
       
   519     TRACE_INFO_SEG(
       
   520         {
       
   521         TBuf<12> buf;
       
   522         aAddr.GetReadable(buf);
       
   523         Trace(_L("[profile remote connect] profile %d, BTAddr '%S' "), aProfile, &buf );
       
   524         });
       
   525     
       
   526     TInt idx = FindAcc(aAddr);
       
   527     if (idx >= 0)
       
   528         {
       
   529         TRAP_IGNORE(iAccs[idx]->AccessoryConnectedL(aAddr, aProfile));
       
   530         }
       
   531     else
       
   532         {
       
   533         CBasrvAcc* acc = NULL;
       
   534         TRAP_IGNORE(acc = CBasrvAcc::NewL(*this));
       
   535         if (acc)
       
   536             {
       
   537             TInt err = iAccs.Append(acc);
       
   538             if (err)
       
   539                 delete acc;
       
   540             else
       
   541                 {
       
   542                 TRAP_IGNORE(acc->AccessoryConnectedL(aAddr, aProfile));
       
   543                 }
       
   544             }
       
   545         }
       
   546     }
       
   547 
       
   548 void CBasrvAccMan::AccessoryDisconnected(const TBTDevAddr& aAddr, TProfiles aProfile)
       
   549     {
       
   550     TRACE_INFO_SEG(
       
   551         {
       
   552         TBuf<12> buf;
       
   553         aAddr.GetReadable(buf);
       
   554         Trace(_L("[profile remote disconnect] profile %d, BTAddr '%S' "), aProfile, &buf );
       
   555         });
       
   556     TInt idx = FindAcc(aAddr);
       
   557     if (idx >= 0)
       
   558         {
       
   559         TRAP_IGNORE(iAccs[idx]->AccessoryDisconnectedL(aProfile));
       
   560         }
       
   561     }
       
   562 
       
   563 void CBasrvAccMan::RemoteAudioOpened(const TBTDevAddr& aAddr, TProfiles aProfile)
       
   564     {
       
   565     TRACE_INFO_SEG(
       
   566         {
       
   567         TBuf<12> buf;
       
   568         aAddr.GetReadable(buf);
       
   569         Trace(_L("[Audio remote open] profile %d, BTAddr '%S' "), aProfile, &buf );
       
   570         });
       
   571 
       
   572     TInt idx = FindAcc(aAddr);
       
   573     if (idx >= 0)
       
   574         {
       
   575         // Check if another audio link opened already
       
   576         TInt audiolinks = AudioLinkStatus();
       
   577         
       
   578         if ( ( audiolinks && audiolinks != aProfile) || 
       
   579             ( iAudioRequests.Count() && 
       
   580               iAudioRequests[0].iOngoing && 
       
   581               iAudioRequests[0].iAddr == aAddr) )
       
   582             {
       
   583             // another audio type is opened while we have an audio link or pending audio request.
       
   584             if (iAudioRequests.Count())
       
   585                 {
       
   586                 TRACE_INFO((_L(" [audio link check] existing audio link %x, audio request pending ? %d. Audio should be rejected!"),
       
   587                         audiolinks, iAudioRequests[0].iOngoing))
       
   588                 }
       
   589             else
       
   590                 {
       
   591                 TRACE_INFO((_L(" [audio link check] existing audio link %x. Audio should be rejected!"),
       
   592                         audiolinks))
       
   593                 }
       
   594             RejectAudioLink(aAddr, (aProfile == EStereo) ? EAccStereoAudio : EAccMonoAudio);
       
   595             }
       
   596         else
       
   597             {
       
   598             iAccs[idx]->AccOpenedAudio(aProfile);
       
   599             }
       
   600         }
       
   601     }
       
   602 
       
   603 void CBasrvAccMan::RemoteAudioClosed(const TBTDevAddr& aAddr, TProfiles aProfile)    
       
   604     {
       
   605     TRACE_INFO_SEG(
       
   606         {
       
   607         TBuf<12> buf;
       
   608         aAddr.GetReadable(buf);
       
   609         Trace(_L("[Audio remote close] profile %d, BTAddr '%S' "), aProfile, &buf );
       
   610         });
       
   611     TInt idx = FindAcc(aAddr);
       
   612     if (idx >= 0)
       
   613         {
       
   614         iAccs[idx]->AccClosedAudio(aProfile);
       
   615         }
       
   616     }
       
   617 
       
   618 TInt CBasrvAccMan::DisableNREC(const TBTDevAddr& aAddr)    
       
   619     {
       
   620     TRACE_FUNC
       
   621     TInt idx = FindAcc(aAddr);
       
   622     if (idx >= 0)
       
   623         {
       
   624             TInt err = KErrNone;
       
   625             TRAPD(trap, err = AccfwConnectionL()->DisableNREC(aAddr));
       
   626             if (trap)
       
   627                 return trap; 
       
   628             return err;
       
   629         }
       
   630     return KErrNotFound; 	    
       
   631     }
       
   632 
       
   633 void CBasrvAccMan::AccessoryTemporarilyUnavailable(const TBTDevAddr& /*aAddr*/, TProfiles /*aType*/)
       
   634     {
       
   635     TRACE_INFO((_L("AccessoryTemporarilyUnavailable Deprecated !!!")))
       
   636     }
       
   637 
       
   638 TInt CBasrvAccMan::ConnectionStatus(const TBTDevAddr& aAddr)
       
   639 	{
       
   640 	TRACE_FUNC
       
   641     TInt count = iAccs.Count();
       
   642     const TAccInfo* info = NULL;
       
   643     for (TInt i = 0; i < count; i++)
       
   644         {
       
   645         info = iAccs[i]->AccInfo(aAddr);
       
   646         if (info)
       
   647             {
       
   648             return info->iConnProfiles;
       
   649             }
       
   650         }
       
   651     return 0;
       
   652 	}
       
   653 
       
   654 void CBasrvAccMan::RequestCompletedL(CBasrvActive& aActive)
       
   655     {
       
   656     TRACE_FUNC
       
   657     switch (aActive.RequestId())
       
   658         {
       
   659         case KOpenAudioListenerId:
       
   660             {
       
   661             if (aActive.iStatus == KErrNone)
       
   662                 {
       
   663                 TAudioRequest req;
       
   664                 req.iAddr = iOpenAddr;
       
   665                 req.iAudioType = iOpenType;
       
   666                 req.iReqType = EOpenReqFromAudioPolicy;
       
   667                 req.iOngoing = EFalse;
       
   668                 
       
   669                 TRACE_INFO_SEG(
       
   670                     {
       
   671                     TBuf<12> buf;
       
   672                     iOpenAddr.GetReadable(buf);
       
   673                     Trace(_L("[Audio Request Buf] 1(Open) %d at '%S'"), iOpenType, &buf);
       
   674                     });
       
   675                 
       
   676                 AccfwConnectionL()->NotifyBTAudioLinkOpenReq(iOpenAddr, aActive.iStatus, iOpenType);
       
   677                 aActive.GoActive();
       
   678                 iAudioRequests.AppendL(req);
       
   679                 DoAudioRequestL();
       
   680                 }
       
   681             break;
       
   682             }
       
   683         case KCloseAudioListenerId:
       
   684             if (aActive.iStatus == KErrNone)
       
   685                 {
       
   686                 TAudioRequest req;
       
   687                 req.iAddr = iCloseAddr;
       
   688                 req.iAudioType = iCloseType;
       
   689                 req.iReqType = ECloseReqFromAudioPolicy;
       
   690                 req.iOngoing = EFalse;
       
   691                 TRACE_INFO_SEG(
       
   692                     {
       
   693                     TBuf<12> buf;
       
   694                     iCloseAddr.GetReadable(buf);
       
   695                     Trace(_L("[Audio Request Buf] 0(Close) %d at '%S'"), iCloseType, &buf);
       
   696                     });
       
   697                 AccfwConnectionL()->NotifyBTAudioLinkCloseReq(iCloseAddr, aActive.iStatus, iCloseType);
       
   698                 aActive.GoActive();
       
   699                 iAudioRequests.AppendL(req);
       
   700                 DoAudioRequestL();
       
   701                 }
       
   702             break;
       
   703         case KShowNoteRequest:
       
   704             {
       
   705             TInt index = iNotifierArray.Find(&aActive);
       
   706             if(index>=0)
       
   707             	{
       
   708             	delete iNotifierArray[index];	
       
   709             	iNotifierArray.Remove(index);
       
   710             	}
       
   711             break;
       
   712             }
       
   713         case KAsyncHandlingRequest:
       
   714             {
       
   715             DoAudioRequestL();
       
   716             delete iAsyncHandlingActive;
       
   717             iAsyncHandlingActive = NULL;
       
   718             break;
       
   719             }
       
   720         default:
       
   721             {
       
   722             
       
   723             }
       
   724         }
       
   725     }
       
   726     
       
   727 void CBasrvAccMan::CancelRequest(CBasrvActive& aActive)
       
   728     {
       
   729     TRACE_FUNC
       
   730     if (aActive.RequestId() == KOpenAudioListenerId)
       
   731         {
       
   732         TRAP_IGNORE(AccfwConnectionL()->CancelNotifyBTAudioLinkOpenReq());
       
   733         }
       
   734     else if (aActive.RequestId() == KCloseAudioListenerId)
       
   735         {
       
   736         TRAP_IGNORE(AccfwConnectionL()->CancelNotifyBTAudioLinkCloseReq());
       
   737         }
       
   738     }
       
   739     
       
   740 CBasrvAccMan::CBasrvAccMan()
       
   741     {
       
   742     }
       
   743     
       
   744 void CBasrvAccMan::DoAudioRequestL()
       
   745     {
       
   746     TRACE_FUNC
       
   747     if (iAudioRequests.Count() && !iAudioRequests[0].iOngoing && (!iAsyncHandlingActive || !iAsyncHandlingActive->IsActive()))
       
   748         {
       
   749         iAudioRequests[0].iOngoing = ETrue;
       
   750         TInt err = KErrNotFound;
       
   751         TInt idx = FindAcc(iAudioRequests[0].iAddr);
       
   752         if (idx >= 0)
       
   753             {
       
   754             if (iAudioRequests[0].iReqType == EOpenReqFromAudioPolicy)
       
   755                 {
       
   756                 TRAP(err, iAccs[idx]->OpenAudioL(iAudioRequests[0].iAudioType));
       
   757                 }
       
   758             else
       
   759                 {
       
   760                 TRAP(err, iAccs[idx]->CloseAudioL(iAudioRequests[0].iAudioType));
       
   761                 }
       
   762             TRACE_INFO_SEG({
       
   763                 if ( iAudioRequests.Count() )
       
   764                     {
       
   765                     TBuf<12> buf;
       
   766                     iAudioRequests[0].iAddr.GetReadable(buf);
       
   767                     Trace(_L("[Audio Request Start] %d %d at '%S', trap %d"), 
       
   768                     iAudioRequests[0].iReqType, iAudioRequests[0].iAudioType, &buf, err);
       
   769                     }
       
   770                 });
       
   771             }
       
   772         if (err)
       
   773             {
       
   774             if (iAudioRequests[0].iReqType == EOpenReqFromAudioPolicy)
       
   775                 OpenAudioCompleted(iAudioRequests[0].iAddr, iAudioRequests[0].iAudioType, err);
       
   776             else if(iAudioRequests[0].iReqType == ECloseReqFromAudioPolicy)
       
   777                 CloseAudioCompleted(iAudioRequests[0].iAddr, iAudioRequests[0].iAudioType, err);
       
   778             }
       
   779         }    
       
   780     }
       
   781 
       
   782 TInt CBasrvAccMan::FindAcc(const TBTDevAddr& aRemote)
       
   783     {
       
   784     TInt count = iAccs.Count();
       
   785     for (TInt i = 0; i < count; i++)
       
   786         {
       
   787         if (iAccs[i]->Remote() == aRemote)
       
   788             {
       
   789             return i;
       
   790             }
       
   791         }
       
   792     return KErrNotFound;
       
   793     }
       
   794 
       
   795 TInt CBasrvAccMan::AudioLinkStatus()
       
   796     {
       
   797     TInt profiles = 0;
       
   798     TInt count = iAccs.Count();
       
   799     for (TInt i = 0; i < count; i++)
       
   800         {
       
   801         profiles |= iAccs[i]->AccInfo().iAudioOpenedProfiles;
       
   802         }  
       
   803     return profiles;
       
   804     }
       
   805     
       
   806 void CBasrvAccMan::RejectAudioLink(const TBTDevAddr& aAddr, TAccAudioType aType)
       
   807     {
       
   808     TAudioRequest req;
       
   809     req.iAddr = aAddr;
       
   810     req.iAudioType = aType;
       
   811     req.iReqType = ERejectAudioOpenedByAcc;
       
   812     req.iOngoing = EFalse;
       
   813     TInt idx = 0;
       
   814     if (iAudioRequests.Count() && iAudioRequests[0].iOngoing)
       
   815         {
       
   816         idx = 1;
       
   817         }
       
   818     TInt err = iAudioRequests.Insert(req, idx);
       
   819     TRACE_INFO_SEG(
       
   820         {
       
   821         TBuf<12> buf;
       
   822         iCloseAddr.GetReadable(buf);
       
   823         Trace(_L("[Audio Request buf] 2(Reject) %d at '%S', to index %d"), iCloseType, &buf, idx);
       
   824         });
       
   825 
       
   826     if (!err && !iAsyncHandlingActive && !iAudioRequests[0].iOngoing)
       
   827         {
       
   828         // Start rejection asynchronously
       
   829         iAsyncHandlingActive = 
       
   830             CBasrvActive::New(*this, CActive::EPriorityStandard, KAsyncHandlingRequest);
       
   831         if (iAsyncHandlingActive)
       
   832             {
       
   833             iAsyncHandlingActive->iStatus = KRequestPending;
       
   834             TRequestStatus* sta = &(iAsyncHandlingActive->iStatus);
       
   835             User::RequestComplete(sta, KErrNone);
       
   836             iAsyncHandlingActive->GoActive();
       
   837             }
       
   838         }
       
   839     }
       
   840 
       
   841 void CBasrvAccMan::CleanupLastItemFromClientRequestsArray(TAny* aPtr)
       
   842     {
       
   843     //cast the pointer passed in to the correct RArray type
       
   844     RArray<TClientRequestCache>& clientRequests = *static_cast<RArray<TClientRequestCache>*>(aPtr);
       
   845     
       
   846     //remove the last item from the array
       
   847     clientRequests.Remove(clientRequests.Count() - 1);
       
   848     }