bluetooth/btstack/linkmgr/SCOSAP.cpp
changeset 0 29b1cd4cb562
--- /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
+	}