bluetooth/btstack/linkmgr/SCOSAP.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements the SCO SAP class
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <bluetooth/logger.h>
       
    19 #include <bt_sock.h>
       
    20 #include <bluetooth/hci/hciframe.h>
       
    21 
       
    22 #include "SCOSAP.h"
       
    23 #include "physicallinksmanager.h"
       
    24 #include "physicallinks.h"
       
    25 #include "hcifacade.h"
       
    26 #include "linkutil.h"
       
    27 #include "linkmuxer.h"
       
    28 
       
    29 #ifdef __FLOG_ACTIVE
       
    30 _LIT8(KLogComponent, LOG_COMPONENT_HCI_CSCOLINK);
       
    31 #endif
       
    32 
       
    33 CSCOLink* CSCOLink::NewLC(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection)
       
    34 	{
       
    35 	LOG_STATIC_FUNC
       
    36 	CSCOLink* s = new(ELeave) CSCOLink(aConnectionMan, aConnection);
       
    37 	CleanupStack::PushL(s);
       
    38 	s->ConstructL();
       
    39 	return s;
       
    40 	}
       
    41 
       
    42 
       
    43 CSCOLink* CSCOLink::NewL(CPhysicalLinksManager& aLinksMan, CPhysicalLink* aPhysicalLink)
       
    44 	{
       
    45 	LOG_STATIC_FUNC
       
    46 	CSCOLink* s = NewLC(aLinksMan, aPhysicalLink);
       
    47 	CleanupStack::Pop();
       
    48 	return s;
       
    49 	}
       
    50 
       
    51 CSCOLink::CSCOLink(CPhysicalLinksManager& aLinksMan, CPhysicalLink* aPhysicalLink)
       
    52 : CBTSynchronousLink(aLinksMan, aPhysicalLink, ESCOLink)
       
    53 	{
       
    54 	LOG_FUNC
       
    55 	iUserHVPacketTypes = EAnySCOPacket;
       
    56 	}
       
    57 
       
    58 void CSCOLink::ConstructL()
       
    59 	{
       
    60 	LOG_FUNC
       
    61 	CBTSynchronousLink::ConstructL();
       
    62 	}
       
    63 
       
    64 CSCOLink::~CSCOLink()
       
    65 	{
       
    66 	LOG_FUNC
       
    67 	}
       
    68 
       
    69 TInt CSCOLink::GetOption(TUint /*aLevel*/, TUint /*aName*/, TDes8& /*aOption*/) const
       
    70 	{
       
    71 	LOG_FUNC
       
    72 	return KErrNotSupported;
       
    73 	}
       
    74 
       
    75 TInt CSCOLink::SAPSetOption(TUint aLevel,TUint aName,const TDesC8 &aOption)
       
    76 /**
       
    77 	Case ESyncSetUserPacketTypes:
       
    78 	Store the user specified pakcet types if at least one of the SCO packet types is set
       
    79 	The packet types bitmask will be passed as a parameter of CPhysicalLink::Connect(const TBTSyncPackets aUserPacketTypes)
       
    80 	in DoActiveOpenL()
       
    81 */
       
    82 	{
       
    83 	LOG_FUNC
       
    84 	TInt rerr = KErrNone;
       
    85 
       
    86 	if(aLevel != KSolBtSCO)
       
    87 		{
       
    88 		rerr = KErrNotSupported;
       
    89 		}
       
    90 	if(rerr == KErrNone)
       
    91 		{
       
    92 		switch (aName)
       
    93 			{
       
    94 			case ESCOSetUserPacketTypes:
       
    95 				{
       
    96 				TUint16 optHVPacketTypes = *reinterpret_cast<const TUint16*>(aOption.Ptr());
       
    97 				if (EAnySCOPacket & optHVPacketTypes) //make sure at least one HV type is supported
       
    98 					{
       
    99 					iUserHVPacketTypes = static_cast<TUint16>(optHVPacketTypes & (EAnySCOPacket));//Just SCO packet types are stored
       
   100 					iUserHVPacketTypes /= EPacketsHV1;
       
   101 					}
       
   102 				else
       
   103 					{
       
   104 					rerr = KErrNotSupported;
       
   105 					}
       
   106 				break;
       
   107 				}
       
   108 
       
   109 			case ESyncUserPacketTypes:
       
   110 				{
       
   111 				TUint16 optHVPacketTypes = *reinterpret_cast<const TUint16*>(aOption.Ptr());
       
   112 				if(TBTSyncPackets::ESyncAnySCOPacket & optHVPacketTypes) //make sure at least one HV type is supported
       
   113 					{
       
   114 					iUserHVPacketTypes = static_cast<TUint16>(optHVPacketTypes & (TBTSyncPackets::ESyncAnySCOPacket));//Just SCO packet types are stored
       
   115 					}
       
   116 				else
       
   117 					{
       
   118 					rerr = KErrNotSupported;
       
   119 					}
       
   120 				break;
       
   121 				}
       
   122 			
       
   123 			default:
       
   124 				rerr = KErrNotSupported;
       
   125 			}
       
   126 		}
       
   127 	return rerr;
       
   128 	}
       
   129 
       
   130 
       
   131 TUint CSCOLink::DoWrite(const TDesC8& aData, TUint /*aOptions*/, TSockAddr* /*aAddr*/)
       
   132 /**
       
   133 	Actually do the write - has been checked for length
       
   134 	In future could write data on a specific SCO "subchannel" if we do that sort of thing
       
   135 	between devices - possibly then use aAddr or aOptions
       
   136 **/
       
   137 	{
       
   138 	LOG_FUNC
       
   139 	TUint retVal = 0;
       
   140 	TInt err = KErrNone;
       
   141 	
       
   142 #ifdef STACK_SCO_DATA
       
   143 	// Trim length of data if necessary
       
   144 	TPtrC8 data = aData.Left(CHctlSynchronousDataFrame::KHCTLMaxSynchronousDataSize);
       
   145 	if (iLinksMan.LinkManagerProtocol().LinkMuxer().CanWriteSCOData())
       
   146 		{
       
   147 		// for now just try to write - if it fails then it doesnt matter - its
       
   148 		// a lot more *s*ynchronous than sticking it in a queue ;-)
       
   149 		LOG(_L("CSCOLink: Can write SCO data..."));
       
   150 		delete iOutboundSCOFrame;
       
   151 		iOutboundSCOFrame = NULL;
       
   152 		const CHCIFacade& facade = iLinksMan.HCIFacade(); 
       
   153 		TRAP(err, iOutboundSCOFrame = facade.NewSynchronousDataFrameL(static_cast<TUint8>(data.Length())));
       
   154 		if(iOutboundSCOFrame && err == KErrNone)
       
   155 			{
       
   156 			// got the frame - so go and use it
       
   157 			facade.FormatSCOData(*iOutboundSCOFrame, iHandle, data);
       
   158 			if (facade.WriteSCOData(*iOutboundSCOFrame) == KErrNone)
       
   159 				{
       
   160 				retVal = data.Length(); // we sent this many bytes
       
   161 				}
       
   162 			}
       
   163 		}
       
   164 	else
       
   165 		{
       
   166 		LOG(_L("CSCOLink: ERROR Cannot write SCO data."));
       
   167 		Socket()->Error(((err == KErrNone) ? KErrInUse : err), MSocketNotify::EErrorSend);
       
   168 		}
       
   169 #else
       
   170 	LOG(_L("CSCOLink: ERROR SCO data via stack not supported."))
       
   171 	Socket()->Error(KErrNotSupported, MSocketNotify::EErrorSend);
       
   172 #endif
       
   173 	return retVal;
       
   174 	}
       
   175 
       
   176 void CSCOLink::PacketTypeChange(THCIErrorCode aErr, THCIConnHandle aConnH, TUint16 aNewPacket)
       
   177 	{
       
   178 	LOG_FUNC
       
   179 	iState->PacketTypeChange(*this, aErr, aConnH, aNewPacket);
       
   180 	}
       
   181 
       
   182 TBool CSCOLink::IsLinkProbablyPossible()
       
   183 	{
       
   184 	LOG_FUNC
       
   185 	return Baseband().IsSCOPossible();
       
   186 	}
       
   187 
       
   188 TInt CSCOLink::MakeConnection(CPhysicalLink* aPhysLink)
       
   189 	{
       
   190 	LOG_FUNC
       
   191 	// Stores packets as sync packet types, uses packets as SCO types.
       
   192 	return aPhysLink->SCOConnect(iUserHVPacketTypes << KSCOvsSyncHVOffset);
       
   193 	}
       
   194 
       
   195 TDes8& CSCOLink::InboundFrame()
       
   196 	{
       
   197 	LOG_FUNC
       
   198 	return iInboundSCOFrame;
       
   199 	}
       
   200 
       
   201 
       
   202 void CSCOLink::SetExtOptions(TBTSyncConnectOpts /*aSyncOpts*/)
       
   203 	{
       
   204 	LOG_FUNC
       
   205 	}