--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/SCOSAP.cpp Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,205 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements the SCO SAP class
+//
+//
+
+#include <bluetooth/logger.h>
+#include <bt_sock.h>
+#include <bluetooth/hci/hciframe.h>
+
+#include "SCOSAP.h"
+#include "physicallinksmanager.h"
+#include "physicallinks.h"
+#include "hcifacade.h"
+#include "linkutil.h"
+#include "linkmuxer.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_HCI_CSCOLINK);
+#endif
+
+CSCOLink* CSCOLink::NewLC(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection)
+ {
+ LOG_STATIC_FUNC
+ CSCOLink* s = new(ELeave) CSCOLink(aConnectionMan, aConnection);
+ CleanupStack::PushL(s);
+ s->ConstructL();
+ return s;
+ }
+
+
+CSCOLink* CSCOLink::NewL(CPhysicalLinksManager& aLinksMan, CPhysicalLink* aPhysicalLink)
+ {
+ LOG_STATIC_FUNC
+ CSCOLink* s = NewLC(aLinksMan, aPhysicalLink);
+ CleanupStack::Pop();
+ return s;
+ }
+
+CSCOLink::CSCOLink(CPhysicalLinksManager& aLinksMan, CPhysicalLink* aPhysicalLink)
+: CBTSynchronousLink(aLinksMan, aPhysicalLink, ESCOLink)
+ {
+ LOG_FUNC
+ iUserHVPacketTypes = EAnySCOPacket;
+ }
+
+void CSCOLink::ConstructL()
+ {
+ LOG_FUNC
+ CBTSynchronousLink::ConstructL();
+ }
+
+CSCOLink::~CSCOLink()
+ {
+ LOG_FUNC
+ }
+
+TInt CSCOLink::GetOption(TUint /*aLevel*/, TUint /*aName*/, TDes8& /*aOption*/) const
+ {
+ LOG_FUNC
+ return KErrNotSupported;
+ }
+
+TInt CSCOLink::SAPSetOption(TUint aLevel,TUint aName,const TDesC8 &aOption)
+/**
+ Case ESyncSetUserPacketTypes:
+ Store the user specified pakcet types if at least one of the SCO packet types is set
+ The packet types bitmask will be passed as a parameter of CPhysicalLink::Connect(const TBTSyncPackets aUserPacketTypes)
+ in DoActiveOpenL()
+*/
+ {
+ LOG_FUNC
+ TInt rerr = KErrNone;
+
+ if(aLevel != KSolBtSCO)
+ {
+ rerr = KErrNotSupported;
+ }
+ if(rerr == KErrNone)
+ {
+ switch (aName)
+ {
+ case ESCOSetUserPacketTypes:
+ {
+ TUint16 optHVPacketTypes = *reinterpret_cast<const TUint16*>(aOption.Ptr());
+ if (EAnySCOPacket & optHVPacketTypes) //make sure at least one HV type is supported
+ {
+ iUserHVPacketTypes = static_cast<TUint16>(optHVPacketTypes & (EAnySCOPacket));//Just SCO packet types are stored
+ iUserHVPacketTypes /= EPacketsHV1;
+ }
+ else
+ {
+ rerr = KErrNotSupported;
+ }
+ break;
+ }
+
+ case ESyncUserPacketTypes:
+ {
+ TUint16 optHVPacketTypes = *reinterpret_cast<const TUint16*>(aOption.Ptr());
+ if(TBTSyncPackets::ESyncAnySCOPacket & optHVPacketTypes) //make sure at least one HV type is supported
+ {
+ iUserHVPacketTypes = static_cast<TUint16>(optHVPacketTypes & (TBTSyncPackets::ESyncAnySCOPacket));//Just SCO packet types are stored
+ }
+ else
+ {
+ rerr = KErrNotSupported;
+ }
+ break;
+ }
+
+ default:
+ rerr = KErrNotSupported;
+ }
+ }
+ return rerr;
+ }
+
+
+TUint CSCOLink::DoWrite(const TDesC8& aData, TUint /*aOptions*/, TSockAddr* /*aAddr*/)
+/**
+ Actually do the write - has been checked for length
+ In future could write data on a specific SCO "subchannel" if we do that sort of thing
+ between devices - possibly then use aAddr or aOptions
+**/
+ {
+ LOG_FUNC
+ TUint retVal = 0;
+ TInt err = KErrNone;
+
+#ifdef STACK_SCO_DATA
+ // Trim length of data if necessary
+ TPtrC8 data = aData.Left(CHctlSynchronousDataFrame::KHCTLMaxSynchronousDataSize);
+ if (iLinksMan.LinkManagerProtocol().LinkMuxer().CanWriteSCOData())
+ {
+ // for now just try to write - if it fails then it doesnt matter - its
+ // a lot more *s*ynchronous than sticking it in a queue ;-)
+ LOG(_L("CSCOLink: Can write SCO data..."));
+ delete iOutboundSCOFrame;
+ iOutboundSCOFrame = NULL;
+ const CHCIFacade& facade = iLinksMan.HCIFacade();
+ TRAP(err, iOutboundSCOFrame = facade.NewSynchronousDataFrameL(static_cast<TUint8>(data.Length())));
+ if(iOutboundSCOFrame && err == KErrNone)
+ {
+ // got the frame - so go and use it
+ facade.FormatSCOData(*iOutboundSCOFrame, iHandle, data);
+ if (facade.WriteSCOData(*iOutboundSCOFrame) == KErrNone)
+ {
+ retVal = data.Length(); // we sent this many bytes
+ }
+ }
+ }
+ else
+ {
+ LOG(_L("CSCOLink: ERROR Cannot write SCO data."));
+ Socket()->Error(((err == KErrNone) ? KErrInUse : err), MSocketNotify::EErrorSend);
+ }
+#else
+ LOG(_L("CSCOLink: ERROR SCO data via stack not supported."))
+ Socket()->Error(KErrNotSupported, MSocketNotify::EErrorSend);
+#endif
+ return retVal;
+ }
+
+void CSCOLink::PacketTypeChange(THCIErrorCode aErr, THCIConnHandle aConnH, TUint16 aNewPacket)
+ {
+ LOG_FUNC
+ iState->PacketTypeChange(*this, aErr, aConnH, aNewPacket);
+ }
+
+TBool CSCOLink::IsLinkProbablyPossible()
+ {
+ LOG_FUNC
+ return Baseband().IsSCOPossible();
+ }
+
+TInt CSCOLink::MakeConnection(CPhysicalLink* aPhysLink)
+ {
+ LOG_FUNC
+ // Stores packets as sync packet types, uses packets as SCO types.
+ return aPhysLink->SCOConnect(iUserHVPacketTypes << KSCOvsSyncHVOffset);
+ }
+
+TDes8& CSCOLink::InboundFrame()
+ {
+ LOG_FUNC
+ return iInboundSCOFrame;
+ }
+
+
+void CSCOLink::SetExtOptions(TBTSyncConnectOpts /*aSyncOpts*/)
+ {
+ LOG_FUNC
+ }