bluetoothengine/btaudioman/src/BTAccSession.cpp
changeset 0 f63038272f30
child 6 6a29d5ad0713
child 15 00f9ee97d895
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: 
       
    15 *     Server class creates the session. This class then recieves the messages from
       
    16 *      client and forward them to server class to be handled. Messages are completed
       
    17 *      with return values recieved from server. 
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include <e32cmn.h>
       
    24 #include "BTAccSession.h"
       
    25 #include "BTAccClientSrv.h"
       
    26 #include "debug.h"
       
    27 #include "BTAccServer.h"
       
    28 #include "basrvaccman.h"
       
    29 #include "BTAccInfo.h"
       
    30 
       
    31 typedef TPckgBuf<TBTDevAddr> TBTDevAddrPckgBuf;
       
    32 
       
    33 // ================= MEMBER FUNCTIONS =======================
       
    34 CBTAccSession* CBTAccSession::NewL(CBasrvAccMan& aAccMan)
       
    35     {
       
    36     return new (ELeave) CBTAccSession(aAccMan);
       
    37     }
       
    38 
       
    39 CBTAccSession::CBTAccSession(CBasrvAccMan& aAccMan) 
       
    40     : iAccMan(aAccMan)
       
    41     {
       
    42     TRACE_FUNC
       
    43     }
       
    44 
       
    45 // destructor
       
    46 CBTAccSession::~CBTAccSession()
       
    47     {
       
    48     TRACE_FUNC
       
    49     if (iConnectMsg.Handle())
       
    50         {
       
    51         iAccMan.CancelConnect(iConnectingAddr);
       
    52         iConnectMsg.Complete(KErrAbort);
       
    53         }    
       
    54     if (iDisconnectMsg.Handle())
       
    55         {
       
    56         iDisconnectMsg.Complete(KErrAbort);
       
    57         }
       
    58     if (iDisconnectAllMsg.Handle())
       
    59         {
       
    60         iDisconnectAllMsg.Complete(KErrAbort);
       
    61         }
       
    62     if (iNotifyProfileMsg.Handle())
       
    63         {
       
    64         iNotifyProfileMsg.Complete(KErrAbort);
       
    65         }
       
    66     iProfileStatusCache.Close();
       
    67     DestructVariant();
       
    68     
       
    69     //clear the accessory managers pointer to this session if it has one
       
    70     iAccMan.ClearProfileNotifySession(*this);
       
    71     
       
    72     //clear the servers reference to this session
       
    73     Server().ClientClosed(*this);
       
    74     }
       
    75 
       
    76 void CBTAccSession::CreateL()
       
    77     {
       
    78     TRACE_FUNC
       
    79     //use CreateL instead of NewSessionL when using Server() to ensure the
       
    80     //session has been created correctly and Server() returns a valid pointer
       
    81     Server().ClientOpened(*this);
       
    82     }
       
    83 
       
    84 void CBTAccSession::ConnectCompleted(TInt aErr, TInt aProfile, const RArray<TBTDevAddr>* aConflicts)
       
    85     {
       
    86     TRACE_FUNC
       
    87     if (iConnectMsg.Handle())
       
    88         {
       
    89         TRACE_INFO((_L("CBTAccSession::ConnectCompleted err %d"), aErr))
       
    90         if (aConflicts)
       
    91             {
       
    92             TBuf8<KBTDevAddrSize * 2> buf;
       
    93             TInt count = aConflicts->Count();
       
    94             for (TInt i = 0; i < count; i++)
       
    95                 {
       
    96                 buf.Append((*aConflicts)[i].Des());
       
    97                 }
       
    98             
       
    99             if (buf.Length())
       
   100                 {
       
   101                 iConnectMsg.Write(1, buf);
       
   102                 }
       
   103             }
       
   104         else if (!aErr)
       
   105             {
       
   106             TPckgBuf<TInt> buf(aProfile);
       
   107             iConnectMsg.Write(1, buf);
       
   108             }
       
   109         iConnectMsg.Complete(aErr);
       
   110         }
       
   111     }
       
   112     
       
   113 void CBTAccSession::DisconnectCompleted(TInt aProfile, TInt aErr)
       
   114     {
       
   115     TRACE_FUNC
       
   116     if (iDisconnectMsg.Handle())
       
   117         {
       
   118         TRACE_FUNC
       
   119         if (!aErr)
       
   120             {
       
   121             TPckgBuf<TInt> buf(aProfile);
       
   122             iDisconnectMsg.Write(1, buf);
       
   123             }
       
   124         iDisconnectMsg.Complete(aErr);
       
   125         }
       
   126     }
       
   127 
       
   128 void CBTAccSession::DisconnectAllCompleted(TInt aErr)
       
   129     {
       
   130     TRACE_FUNC
       
   131     if (iDisconnectAllMsg.Handle())
       
   132         {
       
   133         TRACE_FUNC
       
   134         TRACE_INFO((_L("ERR %d"), aErr))    
       
   135         iDisconnectAllMsg.Complete(aErr);
       
   136         }
       
   137     }
       
   138     
       
   139 // ---------------------------------------------------------
       
   140 // CBTAccSession::ConnectToAccessory
       
   141 // ---------------------------------------------------------
       
   142 void CBTAccSession::ConnectToAccessory(const RMessage2& aMessage)
       
   143     {
       
   144     TRACE_FUNC
       
   145     if (iConnectMsg.Handle())
       
   146         {
       
   147         aMessage.Complete(KErrServerBusy);
       
   148         }
       
   149     else
       
   150         {
       
   151         TInt err;
       
   152         TBTDevAddrPckgBuf pckg;
       
   153         iConnectMsg = aMessage;
       
   154         err = aMessage.Read(0, pckg);
       
   155         if (!err)
       
   156             {
       
   157             iConnectingAddr = pckg();
       
   158             TRAP(err, iAccMan.ConnectL(*this, pckg()));
       
   159             }
       
   160         if (err)
       
   161             {
       
   162             iConnectMsg.Complete(err);
       
   163             }
       
   164         }
       
   165     }
       
   166     
       
   167 // ---------------------------------------------------------
       
   168 // CBTAccSession::ConnectToAccessory
       
   169 // ---------------------------------------------------------
       
   170 void CBTAccSession::CancelConnectToAccessory()
       
   171     {
       
   172     TRACE_FUNC
       
   173      if (iConnectMsg.Handle())
       
   174         {
       
   175         iAccMan.CancelConnect(iConnectingAddr);
       
   176         iConnectMsg.Complete(KErrCancel);
       
   177         }
       
   178     }
       
   179     
       
   180 // ---------------------------------------------------------
       
   181 // CBTAccSession::DisconnectAccessory
       
   182 // ---------------------------------------------------------
       
   183 void CBTAccSession::DisconnectAccessory(const RMessage2& aMessage)
       
   184     {
       
   185     TRACE_FUNC
       
   186     if (iDisconnectMsg.Handle() || iDisconnectAllMsg.Handle())
       
   187         {
       
   188         aMessage.Complete(KErrServerBusy);
       
   189         }
       
   190     else
       
   191         {
       
   192         iDisconnectMsg = aMessage;
       
   193         TBTDevAddrPckgBuf pckg;
       
   194         TInt err = aMessage.Read(0, pckg);
       
   195         if (!err)
       
   196             {
       
   197             TRAP(err, iAccMan.DisconnectL(*this, pckg()));
       
   198             }
       
   199         if (err)
       
   200             {
       
   201             iDisconnectMsg.Complete(err);
       
   202             }
       
   203         }
       
   204     }
       
   205 
       
   206 void CBTAccSession::GetConnections(const RMessage2& aMessage)
       
   207     {
       
   208     TRACE_FUNC
       
   209     TProfiles profile = static_cast<TProfiles>(aMessage.Int1());
       
   210     RPointerArray<const TAccInfo> infos;
       
   211     TInt ret = iAccMan.AccInfos(infos);
       
   212     
       
   213     if (ret == KErrNone)
       
   214         {
       
   215         RBuf8 buf;
       
   216         
       
   217         //get the number of connected accessories
       
   218         TInt accessoryCount = infos.Count();
       
   219         
       
   220         //create a buffer the size of either the client side buffer or the
       
   221         //maximum amount of addresses (number of connected accessories)
       
   222         TInt min = Min(aMessage.GetDesMaxLength(0) / KBTDevAddrSize, accessoryCount);        
       
   223         ret = buf.Create(min * KBTDevAddrSize);
       
   224         
       
   225         //if the buffer was created successfully
       
   226         if (ret == KErrNone)
       
   227             {
       
   228             //iterate through the accessory info array and append the device
       
   229             //addresses to the buffer
       
   230             for (TInt i = 0; i < min; i++)
       
   231                 {
       
   232                 if (infos[i]->iConnProfiles & profile)
       
   233                     {
       
   234                     buf.Append(infos[i]->iAddr.Des());
       
   235                     }
       
   236                 }
       
   237             }
       
   238         
       
   239         //finished with the accessory info array
       
   240         infos.Close();
       
   241         
       
   242         //if there is no error and the buffer has something in,
       
   243         //write the buffer to the message
       
   244         if (ret == KErrNone)
       
   245             {
       
   246             ret = aMessage.Write(0, buf);
       
   247             
       
   248             if (ret == KErrNone)
       
   249                 {
       
   250                 ret = accessoryCount;
       
   251                 }
       
   252             }
       
   253         }
       
   254     
       
   255     //complete the message with either the number of addresses (num of
       
   256     //connected accessories) or a system-wide error code
       
   257     aMessage.Complete(ret);
       
   258     }
       
   259 
       
   260 void CBTAccSession::DisconnectAllGracefully(const RMessage2& aMessage)
       
   261     {
       
   262     TRACE_FUNC
       
   263     if (iDisconnectMsg.Handle() || iDisconnectAllMsg.Handle())
       
   264         {
       
   265         aMessage.Complete(KErrServerBusy);
       
   266         }
       
   267     else
       
   268         {
       
   269         iDisconnectAllMsg = aMessage;
       
   270         TRAPD(err, iAccMan.DisconnectAllL(*this));
       
   271         if (err)
       
   272             {
       
   273             iDisconnectAllMsg.Complete(err);
       
   274             }
       
   275         }
       
   276     }
       
   277 
       
   278 void CBTAccSession::NotifyProfileStatus(const RMessage2& aMessage)
       
   279     {
       
   280     TRACE_FUNC
       
   281     iAccMan.SetProfileNotifySession(*this);    
       
   282     if (iNotifyProfileMsg.Handle())
       
   283         {
       
   284         aMessage.Complete(KErrInUse);
       
   285         }
       
   286     else
       
   287         {
       
   288         if (iProfileStatusCache.Count())
       
   289             {
       
   290             TProfileStatusPckgBuf buf(iProfileStatusCache[0]);
       
   291             TInt err = aMessage.Write(0, buf);
       
   292             aMessage.Complete(err);
       
   293             iProfileStatusCache.Remove(0);
       
   294             }
       
   295         else
       
   296             {
       
   297             iNotifyProfileMsg = aMessage;
       
   298             }
       
   299         }
       
   300     }
       
   301 
       
   302 // ---------------------------------------------------------
       
   303 // CBTAccSession::GetBTAccInfo
       
   304 // ---------------------------------------------------------
       
   305 void CBTAccSession::GetInfoOfConnectedAcc( const RMessage2& aMessage )
       
   306     {
       
   307     TRACE_FUNC
       
   308     TAccInfo info;
       
   309     TPckg<TAccInfo> infoPckg(info);
       
   310     TInt err = aMessage.Read(0, infoPckg);
       
   311     if (!err)
       
   312         {
       
   313         const TAccInfo* infoptr = iAccMan.AccInfo(info.GetBDAddress());
       
   314         if (infoptr)
       
   315             {
       
   316             TPtr8 ptr((TUint8*)infoptr, sizeof(TAccInfo), sizeof(TAccInfo));
       
   317             err = aMessage.Write(0, ptr);
       
   318             }
       
   319         else
       
   320             {
       
   321             err = KErrNotFound;
       
   322             }
       
   323         }
       
   324     aMessage.Complete(err);
       
   325     }
       
   326     
       
   327 void CBTAccSession::IsConnected(const RMessage2& aMessage)
       
   328     {
       
   329     TRACE_FUNC
       
   330     TBTDevAddrPckgBuf pckg;
       
   331     TInt err = aMessage.Read(0, pckg);
       
   332     
       
   333     if (err == KErrNone)
       
   334         {
       
   335         aMessage.Complete(iAccMan.ConnectionStatus4Client(pckg()));
       
   336         }
       
   337     else
       
   338         {
       
   339         aMessage.Complete(err);
       
   340         }
       
   341     }
       
   342 
       
   343 void CBTAccSession::NotifyClientNewProfile(TInt aProfile, const TBTDevAddr& aAddr)
       
   344     {
       
   345     TRACE_FUNC
       
   346     TProfileStatus newp;
       
   347     newp.iAddr = aAddr;
       
   348     newp.iConnected = ETrue;
       
   349     newp.iProfiles = aProfile;
       
   350     if (iNotifyProfileMsg.Handle())
       
   351         {
       
   352         TProfileStatusPckgBuf buf(newp);
       
   353         TInt err = iNotifyProfileMsg.Write(0, buf);
       
   354         iNotifyProfileMsg.Complete(err);        
       
   355         }
       
   356     else
       
   357         {
       
   358         UpdateProfileStatusCache(newp);
       
   359         }
       
   360     }
       
   361     
       
   362 void CBTAccSession::NotifyClientNoProfile(TInt aProfile, const TBTDevAddr& aAddr)
       
   363     {
       
   364     TRACE_FUNC
       
   365     TProfileStatus newp;
       
   366     newp.iAddr = aAddr;
       
   367     newp.iConnected = EFalse;
       
   368     newp.iProfiles = aProfile;
       
   369     if (iNotifyProfileMsg.Handle())
       
   370         {
       
   371         TProfileStatusPckgBuf buf(newp);
       
   372         TInt err = iNotifyProfileMsg.Write(0, buf);
       
   373         iNotifyProfileMsg.Complete(err);        
       
   374         }
       
   375     else
       
   376         {
       
   377         UpdateProfileStatusCache(newp);
       
   378         }
       
   379     }
       
   380 
       
   381 // ---------------------------------------------------------
       
   382 // Server
       
   383 // Return a reference to CBTServer
       
   384 // ---------------------------------------------------------
       
   385 //
       
   386 CBTAccServer& CBTAccSession::Server()
       
   387     {
       
   388     return *static_cast<CBTAccServer*>(const_cast<CServer2*>(CSession2::Server()));
       
   389     }
       
   390 
       
   391 // ---------------------------------------------------------
       
   392 // ServiceL
       
   393 // service a client request; test the opcode and then do
       
   394 // appropriate servicing
       
   395 // ---------------------------------------------------------
       
   396 //
       
   397 void CBTAccSession::ServiceL(const RMessage2& aMessage)
       
   398     {
       
   399     TRACE_FUNC
       
   400     TRACE_INFO((_L("CBTAccSession::DispatchMessageL func %d"), aMessage.Function()))
       
   401     switch (aMessage.Function())
       
   402         {
       
   403         case EBTAccSrvConnectToAccessory:
       
   404             {
       
   405             ConnectToAccessory(aMessage);
       
   406             break;
       
   407             }
       
   408         case EBTAccSrvCancelConnectToAccessory:
       
   409             {
       
   410             CancelConnectToAccessory();
       
   411             aMessage.Complete(KErrNone);
       
   412             break;
       
   413             }
       
   414 
       
   415         case EBTAccSrvDisconnectAccessory:
       
   416             {
       
   417             DisconnectAccessory(aMessage);
       
   418             break;
       
   419             }
       
   420         case EBTAccSrvGetConnections:
       
   421             {
       
   422             GetConnections(aMessage);
       
   423             break;
       
   424             }
       
   425         case EBTAccSrvDisconnectAllGracefully:
       
   426             {
       
   427             DisconnectAllGracefully(aMessage);
       
   428             break;
       
   429             }
       
   430         case EBTAccSrvNotifyConnectionStatus:
       
   431             {
       
   432             NotifyProfileStatus(aMessage);
       
   433             break;
       
   434             }
       
   435         case EBTAccSrvCancelNotifyConnectionStatus:
       
   436             {
       
   437             if (iNotifyProfileMsg.Handle())
       
   438                 {
       
   439                 iNotifyProfileMsg.Complete(KErrCancel);
       
   440                 }
       
   441             aMessage.Complete(KErrNone);
       
   442             break;
       
   443             }
       
   444         case EBTAccSrvConnectionStatus:
       
   445             {
       
   446             IsConnected(aMessage);
       
   447             break;
       
   448             }
       
   449         case EBTAccSrvGetInfoOfConnectedAcc:
       
   450             {
       
   451             GetInfoOfConnectedAcc(aMessage);
       
   452             break;
       
   453             }
       
   454         case EBTAccSrvAudioToPhone:
       
   455         case EBTAccSrvAudioToAccessory:
       
   456         case EBTAccSrvCancelAudioToAccessory:
       
   457             {
       
   458             HandleAudio4DosRequest(aMessage);
       
   459             break;
       
   460             }
       
   461         default:
       
   462             {
       
   463             PanicClient(aMessage, EBTAccBadRequest);
       
   464             break;
       
   465             }
       
   466         }
       
   467     }
       
   468 
       
   469 void CBTAccSession::UpdateProfileStatusCache(const TProfileStatus& aStatus)
       
   470     {
       
   471     TRACE_FUNC
       
   472     TInt count = iProfileStatusCache.Count();
       
   473     for (TInt i = 0; i < count; i++)
       
   474         {
       
   475         if (iProfileStatusCache[i].iAddr == aStatus.iAddr && 
       
   476             iProfileStatusCache[i].iProfiles == aStatus.iProfiles)
       
   477             {
       
   478             iProfileStatusCache[i].iConnected = aStatus.iConnected;
       
   479             return;
       
   480             }
       
   481         }
       
   482     iProfileStatusCache.Append(aStatus);
       
   483     }
       
   484 
       
   485 // End of File