diff -r 14e240312f6f -r 786b94c6f0a4 bluetoothmgmt/bluetoothclientlib/btlib/btsynclink.cpp --- a/bluetoothmgmt/bluetoothclientlib/btlib/btsynclink.cpp Thu Jul 15 19:55:36 2010 +0300 +++ b/bluetoothmgmt/bluetoothclientlib/btlib/btsynclink.cpp Thu Aug 19 11:01:00 2010 +0300 @@ -160,7 +160,6 @@ // This needs to be a macro or the 'return' won't return properly #define CLOSE_RETURN_IF_ERROR(error) if (error) { LinkDown(); SCOSocket().Close(); ESCOSocket().Close(); return error; } -#define CLOSE_LISTENER_RETURN_IF_ERROR(error) if (error) { ListeningSCOSocket().Close(); ListeningESCOSocket().Close(); return error; } EXPORT_C TInt CBluetoothSynchronousLink::SetupConnection(const TBTDevAddr& aBDAddr, const TBTSyncPackets& aPacketTypes) { @@ -191,23 +190,17 @@ if (packetsESCO) { iSCOTypes |= EeSCO; - openESCO = ETrue; + openESCO = ETrue; } // but must be one __ASSERT_ALWAYS(packetsSCO || packetsESCO, Panic(EBadSyncPacketTypes)); - if (iBTSynchronousLinkAttacherSCO->IsActive()) + if (iBTSynchronousLinkAttacherSCO->IsActive() || iBTSynchronousLinkAttacherESCO->IsActive()) { FLOG(_L("Link attacher already active")); return KErrInUse; } - - if (iBTSynchronousLinkAttacherESCO->IsActive()) - { - FLOG(_L("Link attacher already active")); - return KErrInUse; - } TInt linkState = LinkUp(aBDAddr); if (linkState != KErrNone) @@ -337,16 +330,12 @@ */ EXPORT_C TInt CBluetoothSynchronousLink::Disconnect() { - if (!SCOSocket().SubSessionHandle()) + if (!SCOSocket().SubSessionHandle() && !ESCOSocket().SubSessionHandle()) { - if(!ESCOSocket().SubSessionHandle()) - { - return KErrDisconnected; - } + return KErrDisconnected; } - if (iBTSynchronousLinkDetacherSCO->IsActive() || - iBTSynchronousLinkDetacherESCO->IsActive()) + if (iBTSynchronousLinkDetacherSCO->IsActive() || iBTSynchronousLinkDetacherESCO->IsActive()) { return KErrInUse; } @@ -499,6 +488,12 @@ */ EXPORT_C TInt CBluetoothSynchronousLink::AcceptConnection(const TBTSyncPackets& aPacketTypes) { + TRAPD(err, AcceptConnectionL(aPacketTypes)); + return err; + } + +void CBluetoothSynchronousLink::AcceptConnectionL(const TBTSyncPackets& aPacketTypes) + { TBool listenForSCO = EFalse; TBool listenForESCO = EFalse; @@ -506,41 +501,30 @@ TBTSyncPacketTypes packets = aPacketTypes(); - __ASSERT_ALWAYS(packets, Panic(EBadSyncPacketTypes)); packets &= (TBTSyncPackets::ESyncAnySCOPacket | TBTSyncPackets::ESyncAnyESCOPacket); if (!packets) { - return KErrNotSupported; + User::Leave(KErrNotSupported); } - if (iBTSynchronousLinkAccepterSCO->IsActive()) + if (iBTSynchronousLinkAccepterSCO->IsActive() || iBTSynchronousLinkAccepterESCO->IsActive()) { - return KErrInUse; - } - - if (iBTSynchronousLinkAccepterESCO->IsActive()) - { - return KErrInUse; + User::Leave(KErrInUse); } - TInt err = ListeningSCOSocket().Open(iSockServer, KBTAddrFamily, KSockBluetoothTypeSCO, KBTLinkManager); - if(err) - { - return err; - } + User::LeaveIfError(ListeningSCOSocket().Open(iSockServer, KBTAddrFamily, KSockBluetoothTypeSCO, KBTLinkManager)); + CleanupClosePushL(ListeningSCOSocket()); - err = ListeningESCOSocket().Open(iSockServer, KBTAddrFamily, KSockBluetoothTypeESCO, KBTLinkManager); - if(err) - { - ListeningSCOSocket().Close(); - return err; - } + User::LeaveIfError(ListeningESCOSocket().Open(iSockServer, KBTAddrFamily, KSockBluetoothTypeESCO, KBTLinkManager)); + CleanupClosePushL(ListeningESCOSocket()); + + CleanupStack::PushL(TCleanupItem(StaticResetScoTypes, this)); // we want to clear any setting of SCO types upon leaving TBTSyncPacketTypes packetsSCO = packets & TBTSyncPackets::ESyncAnySCOPacket; if (packetsSCO) { - err = ListeningSCOSocket().SetOpt(ESyncUserPacketTypes, KSolBtSCO, packetsSCO); + TInt err = ListeningSCOSocket().SetOpt(ESyncUserPacketTypes, KSolBtSCO, packetsSCO); if(!err) { iSCOTypes |= ESCO; @@ -551,17 +535,15 @@ TBTSyncPacketTypes packetsESCO = packets & TBTSyncPackets::ESyncAnyESCOPacket; if (packetsESCO) { - err = ListeningESCOSocket().SetOpt(ESyncUserPacketTypes, KSolBtSCO, packetsESCO); + TInt err = ListeningESCOSocket().SetOpt(ESyncUserPacketTypes, KSolBtSCO, packetsESCO); if (!err) { iSCOTypes |= EeSCO; listenForESCO = ETrue; + + TPckgC options(iRequestedLink); + User::LeaveIfError(ListeningESCOSocket().SetOpt(EeSCOExtOptions, KSolBtESCO, options)); } - - TPckgBuf options; - options() = iRequestedLink; - err = ListeningESCOSocket().SetOpt(EeSCOExtOptions, KSolBtESCO, options); - CLOSE_LISTENER_RETURN_IF_ERROR(err); } __ASSERT_ALWAYS(listenForSCO || listenForESCO, Panic(EBadSyncPacketTypes)); @@ -580,62 +562,57 @@ if (listenForSCO) { - err = ListeningSCOSocket().Bind(sa); - CLOSE_LISTENER_RETURN_IF_ERROR(err); - - err = ListeningSCOSocket().Listen(KSCOListenQueSize); - CLOSE_LISTENER_RETURN_IF_ERROR(err); - - err = SCOSocket().Open(SocketServer()); - if(err) - { - return err; - } + User::LeaveIfError(ListeningSCOSocket().Bind(sa)); + User::LeaveIfError(ListeningSCOSocket().Listen(KSCOListenQueSize)); + User::LeaveIfError(SCOSocket().Open(SocketServer())); + CleanupClosePushL(SCOSocket()); } if(listenForESCO) { - err = ListeningESCOSocket().Bind(sa); - CLOSE_LISTENER_RETURN_IF_ERROR(err); - - err = ListeningESCOSocket().Listen(KSCOListenQueSize); - CLOSE_LISTENER_RETURN_IF_ERROR(err); + User::LeaveIfError(ListeningESCOSocket().Bind(sa)); + User::LeaveIfError(ListeningESCOSocket().Listen(KSCOListenQueSize)); + User::LeaveIfError(ESCOSocket().Open(SocketServer())); + } + + // Now we can't fail synchronously, so we're ready to begin the accept. + if(listenForESCO) + { + iBTSynchronousLinkAccepterESCO->Accept(); + } - err = ESCOSocket().Open(SocketServer()); - if(err) - { - return err; - } - } - if (listenForSCO) { - iBTSynchronousLinkAccepterSCO->Accept(ListeningSCOSocket()); + CleanupStack::Pop(&SCOSocket()); + iBTSynchronousLinkAccepterSCO->Accept(); } - if(listenForESCO) - { - iBTSynchronousLinkAccepterESCO->Accept(ListeningESCOSocket()); - } + CleanupStack::Pop(3); // StaticResetScoTypes, ListeningESCOSocket(), ListeningSCOSocket() + } - return err; +void CBluetoothSynchronousLink::StaticResetScoTypes(TAny* aThis) + { + static_cast(aThis)->iSCOTypes = 0; } /** Cancel ability to respond to a remote request to set up a synchronous link. -It is possible for a race condition to mean that a connection has been established, -but as this call consumes the callback, for this fact not to reach the caller. -For this reason, it may be desirable to follow a call to CancelAccept with a call -to Disconnect. -@see CBluetoothSynchronousLink::Disconnect + +It is possible for a race condition to mean that a connection has been established +but the notifier has not yet received the call-back. In this case no call-back will +be received and the link (if established) will be immediately shutdown. */ EXPORT_C void CBluetoothSynchronousLink::CancelAccept() { iBTSynchronousLinkAccepterSCO->Cancel(); iBTSynchronousLinkAccepterESCO->Cancel(); iBTSynchronousLinkBaseband->StopAll(); - + + iSCOTypes = 0; + + LinkDown(); + ListeningSCOSocket().Close(); ListeningESCOSocket().Close(); SCOSocket().Close(); @@ -896,36 +873,48 @@ if (aSCOType & ESCO) { iBTSynchronousLinkAccepterESCO->Cancel(); + ListeningESCOSocket().Close(); + ESCOSocket().Close(); + SCOSocket().RemoteName(sockAddr); } else { iBTSynchronousLinkAccepterSCO->Cancel(); + ListeningSCOSocket().Close(); + SCOSocket().Close(); + ESCOSocket().RemoteName(sockAddr); } if(sockAddr.Family() == KBTAddrFamily) { - TBTSockAddr& btSockAddr = static_cast(sockAddr); // subclasses of TSockAddr are forbidden to add members + TBTSockAddr& btSockAddr = static_cast(sockAddr); TBTDevAddr da = btSockAddr.BTAddr(); - TInt linkState = LinkUp(da); - - __ASSERT_ALWAYS((linkState == KErrNone), Panic(EBasebandFailedConnect)); - - iBTSynchronousLinkBaseband->PreventPark(); - iBTSynchronousLinkBaseband->CatchEvents(); - UpdateLinkParams(aSCOType); + aErr = LinkUp(da); + if(aErr == KErrNone) + { + iBTSynchronousLinkBaseband->PreventPark(); + iBTSynchronousLinkBaseband->CatchEvents(); + UpdateLinkParams(aSCOType); + } + else + { + FTRACE(FPrint(_L("Failed to \"LinkUp\" the synchronous link (aErr %d)"), aErr)); + } } else { // reading RemoteName has failed, probably socket state is already closed // for example after quick disconnection initiated from remote side - aErr = KErrDisconnected; + aErr = KErrDisconnected; } } - else + + if(aErr != KErrNone) { iNegotiatedLink = TBTeSCOLinkParams(0, 0, 0, 0); + CancelAccept(); // makes sure everything is cleaned up. } #ifdef __FLOGGING__ @@ -935,9 +924,6 @@ #else Notifier().HandleAcceptConnectionCompleteL(aErr); #endif - - ListeningSCOSocket().Close(); - ListeningESCOSocket().Close(); } @@ -1034,24 +1020,16 @@ CBTSynchronousLinkBaseband* CBTSynchronousLinkBaseband::NewL(CBluetoothSynchronousLink& aParent) { CBTSynchronousLinkBaseband* self = new(ELeave) CBTSynchronousLinkBaseband(aParent); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); return self; } CBTSynchronousLinkBaseband::CBTSynchronousLinkBaseband(CBluetoothSynchronousLink& aParent) : CActive(CActive::EPriorityStandard), iParent(aParent) - {} - - -void CBTSynchronousLinkBaseband::ConstructL() { CActiveScheduler::Add(this); } - CBTSynchronousLinkBaseband::~CBTSynchronousLinkBaseband() { StopAll(); @@ -1093,7 +1071,7 @@ Cancel(); } - + void CBTSynchronousLinkBaseband::DoCancel() { iParent.Baseband().CancelNextBasebandChangeEventNotifier(); @@ -1104,20 +1082,12 @@ CBTSynchronousLinkAttacher* CBTSynchronousLinkAttacher::NewL(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) { CBTSynchronousLinkAttacher* self = new (ELeave) CBTSynchronousLinkAttacher(aParent, aSCOType); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); return self; } - CBTSynchronousLinkAttacher::CBTSynchronousLinkAttacher(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) : CActive(CActive::EPriorityStandard), iParent(aParent), iSCOType(aSCOType) { - } - -void CBTSynchronousLinkAttacher::ConstructL() - { CActiveScheduler::Add(this); } @@ -1155,7 +1125,6 @@ return KErrNone; } - void CBTSynchronousLinkAttacher::DoCancel() { FLOG(_L("CBTSynchronousLinkAttacher cancel attach sync link")); @@ -1174,20 +1143,12 @@ CBTSynchronousLinkDetacher* CBTSynchronousLinkDetacher::NewL(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) { CBTSynchronousLinkDetacher* self = new (ELeave) CBTSynchronousLinkDetacher(aParent, aSCOType); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); return self; } - CBTSynchronousLinkDetacher::CBTSynchronousLinkDetacher(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) : CActive(CActive::EPriorityStandard), iParent(aParent), iSCOType(aSCOType) { - } - -void CBTSynchronousLinkDetacher::ConstructL() - { CActiveScheduler::Add(this); } @@ -1240,9 +1201,6 @@ CBTSynchronousLinkAccepter* CBTSynchronousLinkAccepter::NewL(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) { CBTSynchronousLinkAccepter* self = new (ELeave) CBTSynchronousLinkAccepter(aParent, aSCOType); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); return self; } @@ -1250,10 +1208,6 @@ CBTSynchronousLinkAccepter::CBTSynchronousLinkAccepter(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) : CActive(CActive::EPriorityStandard), iParent(aParent), iSCOType(aSCOType) { - } - -void CBTSynchronousLinkAccepter::ConstructL() - { CActiveScheduler::Add(this); } @@ -1262,7 +1216,7 @@ Cancel(); } -void CBTSynchronousLinkAccepter::Accept(RSocket& aSocket) +void CBTSynchronousLinkAccepter::Accept() { __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness)); @@ -1270,11 +1224,11 @@ FLOG(_L("CBTSynchronousLinkAccepter accept sync link")); if (iSCOType == ESCO) { - aSocket.Accept(iParent.SCOSocket(), iStatus); + iParent.ListeningSCOSocket().Accept(iParent.SCOSocket(), iStatus); } else { - aSocket.Accept(iParent.ESCOSocket(), iStatus); + iParent.ListeningESCOSocket().Accept(iParent.ESCOSocket(), iStatus); } SetActive(); } @@ -1315,9 +1269,6 @@ CBTSynchronousLinkSender* CBTSynchronousLinkSender::NewL(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) { CBTSynchronousLinkSender* self = new (ELeave) CBTSynchronousLinkSender(aParent, aSCOType); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); return self; } @@ -1325,10 +1276,6 @@ CBTSynchronousLinkSender::CBTSynchronousLinkSender(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) : CActive(CActive::EPriorityStandard), iParent(aParent), iSCOType(aSCOType) { - } - -void CBTSynchronousLinkSender::ConstructL() - { CActiveScheduler::Add(this); } @@ -1403,9 +1350,6 @@ CBTSynchronousLinkReceiver* CBTSynchronousLinkReceiver::NewL(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) { CBTSynchronousLinkReceiver* self = new (ELeave) CBTSynchronousLinkReceiver(aParent, aSCOType); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); return self; } @@ -1413,10 +1357,6 @@ CBTSynchronousLinkReceiver::CBTSynchronousLinkReceiver(CBluetoothSynchronousLink& aParent, TSCOType aSCOType) : CActive(CActive::EPriorityStandard), iParent(aParent), iSCOType(aSCOType) { - } - -void CBTSynchronousLinkReceiver::ConstructL() - { CActiveScheduler::Add(this); }