bluetoothmgmt/bluetoothclientlib/avlib/avdtpTypes.cpp
changeset 0 29b1cd4cb562
child 23 5b153be919d4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/bluetoothclientlib/avlib/avdtpTypes.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,697 @@
+// 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:
+//
+
+#include <bluetoothav.h>
+#include "gavdpinterface.h"
+
+enum TBTAVPanic
+	{
+	EBadArgument,
+	EBTAVBadSEID,
+	EBTAVUnusedOrdinal,
+	};
+	
+void Panic(TBTAVPanic aPanic)
+	{
+	_LIT(KBTAVPanicName, "BluetoothAV Panic");
+	User::Panic(KBTAVPanicName, aPanic);
+	}
+
+const TInt KAVDTPPortSessionOffset	=8;
+const TInt KAVDTPPortSessionMask	=0x03;
+const TInt KAVDTPPortSEIDOffset		=0;
+const TInt KAVDTPPortSEIDMask		=0x3f;
+
+// const TInt KMinMediaCodecLOSC = 2; // mediatype, codectype - see figure8-50 AVDTP
+// const TInt KMinContentProtectionLOSC = 2; // protectiontype
+
+static const TUint KAvdtpSockAddrLocalMask = static_cast<TUint>(1<<31);
+
+/**
+Default constructor using 0 as the parameter for setPort()
+@publishedPartner
+@released
+*/
+EXPORT_C TAvdtpSockAddr::TAvdtpSockAddr() : TBTSockAddr()
+	{
+	SetPort(0);
+	}
+
+/**
+Copy constructor
+@publishedPartner
+@released
+@param aAddr reference to the original socket address
+*/
+EXPORT_C TAvdtpSockAddr::TAvdtpSockAddr(const TSockAddr& aAddr)
+	: TBTSockAddr(aAddr)
+	{
+	}
+
+/**
+Sets the AVDTP session type into the socket address
+@publishedPartner
+@released
+@param aSession the session (eg EMedia)
+*/
+EXPORT_C void TAvdtpSockAddr::SetSession(TAvdtpTransportSessionType aSession)
+	{
+	TInt port = Port();
+	// clear out current session part
+	port &= ~(KAVDTPPortSessionMask << KAVDTPPortSessionOffset);
+	// set new session part
+	port |= (aSession & KAVDTPPortSessionMask) << KAVDTPPortSessionOffset;
+	SetPort(port);
+	}
+	
+/**
+Getter for session from socket address
+@publishedPartner
+@released
+@return the session type
+*/
+EXPORT_C TAvdtpTransportSessionType TAvdtpSockAddr::Session() const
+	{
+	return static_cast<TAvdtpTransportSessionType>
+			((Port() >> KAVDTPPortSessionOffset) & KAVDTPPortSessionMask);
+	}
+
+/**
+Sets the Stream endpoint identifier (SEID) into the socket address
+@publishedPartner
+@released
+@param aSEID the SEID to set - can be remote or local
+*/
+EXPORT_C void TAvdtpSockAddr::SetSEID(TSEID aSEID)
+	{
+/*
+	format of port is
+	lowest octet: used for SEID (only l.s.6 bits meaningful at present)
+	next octet  : used for session type (only l.s.2 bits at present)
+	
+*/
+	TUint port = Port();
+	// clear out current SEID part
+	port &= ~(KAVDTPPortSEIDMask << KAVDTPPortSEIDOffset);
+
+	// put local info at top bit
+	port &= ~KAvdtpSockAddrLocalMask; 
+	if (aSEID.IsLocal())
+		{
+		port |= KAvdtpSockAddrLocalMask; 
+		}
+		
+	// set new SEID part
+	port |= (aSEID.Value() & KAVDTPPortSEIDMask) << KAVDTPPortSEIDOffset;
+	SetPort(port);
+	}
+
+/**
+Getter for the stream endpoint identifier (SEID) from the socket address
+@publishedPartner
+@released
+@return the SEID
+*/	
+EXPORT_C TSEID TAvdtpSockAddr::SEID() const
+	{
+	TUint port = Port();
+	// see if LocalSeid
+	TBool isLocal = port & KAvdtpSockAddrLocalMask;
+	// clear out that bit
+	port &=~KAvdtpSockAddrLocalMask;
+	return TSEID((port & KAVDTPPortSEIDMask) >> KAVDTPPortSEIDOffset, isLocal);
+	}
+
+/**
+Utility function to downcast a TSockAddr to a TAvdtpSockAddr
+@publishedPartner
+@released
+@param aAddr reference to base class socket address
+@return the downcast reference
+*/
+EXPORT_C TAvdtpSockAddr& TAvdtpSockAddr::Cast(const TSockAddr& aAddr)
+	{
+	return *const_cast<TAvdtpSockAddr*>(static_cast<const TAvdtpSockAddr*>(&aAddr));
+	}
+	
+const TUint TSEID::KInvalidSEID = KMaxTUint8;
+
+
+/**
+Default constructor using KInvalidSEID as the stream endpoint identifier (SEID) value
+@publishedPartner
+@released
+*/
+EXPORT_C TSEID::TSEID() : iValue(KInvalidSEID)
+	{
+	}
+
+/**
+Constructor taking a stream endpoint identifier (SEID) value, and whether it refers to a local or remote endpoint
+@publishedPartner
+@released
+@param aSEID, the SEID
+@param aIsLocal ETrue if refers to a local endpoint, else EFalse
+*/ 	
+EXPORT_C TSEID::TSEID(TUint aSEID, TBool aIsLocal) : iValue(aSEID)
+	{
+	iValue|=aIsLocal ? KIsLocalBit : 0;
+	}
+
+/**
+Constructor taking a direct stream endpoint identifier (SEID) value
+@internalTechnology
+@param aValue, the direct value
+*/
+EXPORT_C TSEID::TSEID(TUint aValue)
+	{
+	iValue = aValue;
+	}
+
+/**
+Getter for the stream endpoint identifier (SEID) value, regardless of whether local or remote
+@publishedPartner
+@released
+@return the SEID value
+*/
+EXPORT_C TUint TSEID::SEID() const
+	{
+	// clear local bit
+	return (iValue&~KIsLocalBit);
+	}
+
+/**
+Getter for INTERNAL stream endpoint identifier (SEID) value - for actual SEID value use SEID()
+@internalTechnology
+@see SEID
+@return internal value
+*/
+EXPORT_C TUint TSEID::Value() const
+	{
+	return iValue;
+	}
+
+/**
+Getter for SEID value in packet format
+@internalTechnology
+@return Packet value of SEID
+*/
+EXPORT_C TUint TSEID::PacketValue() const
+	{
+	__ASSERT_ALWAYS(IsValid(), Panic(EBTAVBadSEID));
+	return (SEID() << KAvdtpPacketSEIDOffset); 
+	}
+
+/**
+Checks whether the SEID is allowed by the AVDTP Specification
+@publishedPartner
+@released
+@return ETrue if valid, else EFalse
+*/
+EXPORT_C TBool TSEID::IsValid() const
+	{
+	return (SEID()>=KMinimumRealSEID && SEID()<=KMaximumRealSEID);
+	}
+
+/**
+Set SEID value directly
+@internalTechnology
+@param aValue value to set
+*/ 	
+EXPORT_C void TSEID::Set(TUint aValue)
+	{
+	// don't allow changing of local/remoteness
+	iValue = aValue | (iValue & KIsLocalBit);
+	__ASSERT_ALWAYS(IsValid(), Panic(EBTAVBadSEID));
+	}
+
+/**
+Comparison operator
+@publishedPartner
+@released
+@param right hand operand 
+@return ETrue if aSEID equal to this SEID (the right hand operand), else EFalse
+*/
+EXPORT_C TBool TSEID::operator==(TSEID aSEID) const
+	{
+	return aSEID.Value()==Value();
+	}
+	
+/**
+Negative comparison operator
+@publishedPartner
+@released
+@param right hand operand
+@return EFalse if aSEID equal to this SEID (the right hand operand), else ETrue
+*/
+EXPORT_C TBool TSEID::operator!=(TSEID aSEID) const
+	{
+	return aSEID.Value()!=Value();
+	}
+	
+
+/**
+Not used
+@internalTechnology
+*/
+/*static*/ EXPORT_C TSEID TSEID::_Spare(TUint8 /*aUnused*/)
+	{
+	Panic(EBTAVUnusedOrdinal);
+	return TSEID(0);
+	}
+
+/**
+Helper to create a SEID from a packet value. Leaves if invalid
+@internalTechnology
+@param aPacketValue the value in the packet format
+@leave EAvdtpBadACPSEID (converts to -18062) if created SEID is invalid
+@return new SEID object
+*/
+EXPORT_C /*static*/ TSEID TSEID::FromPacketL(TUint8 aPacketValue, TBool aIsLocal)
+	{
+	TSEID seid((aPacketValue>>KAvdtpPacketSEIDOffset) & KAvdtpPacketSEIDMask, aIsLocal);
+	if (!seid.IsValid())
+		{
+		User::Leave(SymbianBluetoothAV::ConvertToSymbianError::AvdtpError(EAvdtpBadACPSEID));
+		}
+	return seid;
+	}
+	
+/**
+Reset any internal state and values
+@publishedPartner
+@released
+*/
+EXPORT_C void TSEID::Reset()
+	{
+	iValue = KInvalidSEID;
+	}
+	
+/**
+Tests whether the SEID refers to a local endpoint
+@publishedPartner
+@released
+@return ETrue if SEID refers to local endpoint, else EFalse
+*/
+EXPORT_C TBool TSEID::IsLocal() const
+	{
+	return (iValue & KIsLocalBit ? ETrue : EFalse);
+	}
+
+/**
+Constructor of object returned during Discover phase
+@publishedPartner
+@released
+@see AVDTP specification, AVDTP_DiscoverRsp
+*/	
+EXPORT_C TAvdtpSEPInfo::TAvdtpSEPInfo()
+:iInUse(EFalse)
+	{
+	// SEID default constructed - others don't care
+	}
+
+/**
+Getter for the SEID
+@publishedPartner
+@released
+@return the SEID
+*/
+EXPORT_C TSEID TAvdtpSEPInfo::SEID() const
+	{
+	return iSEID;
+	}
+	
+/**
+Getter for whether the Stream End Point (SEP) is in use
+@publishedPartner
+@released
+@return ETrue if the SEP is in use, else EFalse
+*/
+EXPORT_C TBool TAvdtpSEPInfo::InUse() const
+	{
+	return iInUse;
+	}
+	
+/**
+Getter for the SEP mediatype
+@publishedPartner
+@released
+@return Media type of SEP
+*/
+EXPORT_C SymbianBluetoothAV::TBluetoothMediaType TAvdtpSEPInfo::MediaType() const
+	{
+	return iMediaType;
+	}
+	
+/**
+Getter for whether the SEP is sink or source
+@publishedPartner
+@released
+@return ETrue if SEP is a sink, else EFalse;
+*/
+EXPORT_C TBool TAvdtpSEPInfo::IsSink() const
+	{
+	return iIsSink;
+	}
+	
+/**
+Setter for the SEID of the Stream End Point (SEP)
+@internalTechnology
+@param aSEID the SEID to set
+*/
+EXPORT_C void TAvdtpSEPInfo::SetSEID(TSEID aSEID)
+	{
+	iSEID = aSEID;
+	}
+	
+/**
+Setter for the SEP's inUse flag
+@internalTechnology
+@param aIsInUse ETrue if in use
+*/
+EXPORT_C void TAvdtpSEPInfo::SetInUse(TBool aIsInUse)
+	{
+	iInUse = aIsInUse;
+	}
+	
+/**
+Setter for the SEP mediatype
+@publishedPartner
+@released
+@param aMediaType Mediatype of SEP
+*/
+EXPORT_C void TAvdtpSEPInfo::SetMediaType(SymbianBluetoothAV::TBluetoothMediaType aMediaType)
+	{
+	iMediaType = aMediaType;
+	}
+	
+/**
+Setter for whether the SEP is source or sink
+@publishedPartner
+@released
+@param aIsSink ETrue if SEP is a sink, else ETrue;
+*/
+EXPORT_C void TAvdtpSEPInfo::SetIsSink(TBool aIsSink)
+	{
+	iIsSink = aIsSink;
+	}	
+
+/**
+Constructor
+@internalTechnology
+*/
+EXPORT_C CCapabilitySummaryVisitor::CCapabilitySummaryVisitor()
+	{
+	}
+	
+/**
+Setter for the seen capabilities
+@internalTechnology
+@param aCat the Service Category
+@return ETrue
+*/
+TBool CCapabilitySummaryVisitor::Capability(TAvdtpServiceCategory aCat)
+	{
+	// can ignore payload
+	
+	// just mask in category to "seen" record!
+	iSeen.SetCapability(aCat);
+	return ETrue; // always continue
+	}
+	
+/**
+Getter for the seen capabilities
+@internalTechnology
+@return the seen capabilities 
+*/
+EXPORT_C TAvdtpServiceCategories CCapabilitySummaryVisitor::CapabilitiesPresent() const
+	{
+	return iSeen;
+	}
+
+	
+/**
+Constructor
+@internalTechnology
+@param aRequiredCapability the required capability
+*/
+EXPORT_C CCapabilityPresentVisitor::CCapabilityPresentVisitor(TAvdtpServiceCategory aRequiredCapability)
+: iRequiredCapability(aRequiredCapability)
+	{
+	}
+
+/**
+Checks if a capability is the required one
+@internalTechnology
+@param aCat the capability
+@return ETrue if the capability is required else EFalse 
+*/
+
+TBool CCapabilityPresentVisitor::Capability(TAvdtpServiceCategory aCat)
+	{
+	iPresent = (aCat==iRequiredCapability);
+	return !iPresent;
+	}
+
+/**
+Constructor
+@internalTechnology
+@param aRequiredCategories the required capabilities
+*/
+EXPORT_C CCapabilityParseVisitor::CCapabilityParseVisitor(TAvdtpServiceCategories aRequiredCategories)
+: iRequiredCategories(aRequiredCategories)
+	{
+	}
+	
+/**
+Sets up a capability
+@internalTechnology
+@param aCat the capability category
+@param aCapPayload the capability payload
+@return ETrue if the visitor could continue with setting another cabability else EFalse 
+*/
+TBool CCapabilityParseVisitor::Capability(TAvdtpServiceCategory aCat)
+	{
+	TInt result = KErrNone;
+	
+	iCapabilities[aCat] = NULL;
+	if (aCat & iRequiredCategories())
+		{
+		TRAP(result, iCapabilities[aCat] = TAvdtpServiceCapability::AllocFromPDUL(aCat, CapabilityPayload()));
+		}
+	
+	// return true as we try to parse all of the required caps, unless failed, then try to continue
+	// - the visitor loop can decide when it's got to the end of the data
+	TBool keepGoing = EFalse;
+	if ((result == KErrNone) || (result == KErrNotSupported)) 
+		{
+		keepGoing = ETrue;
+		}
+	
+	return keepGoing;
+	}
+	
+/**
+Transfer ownership of capabilities array
+@internalTechnology
+@return the capabilities array
+*/
+EXPORT_C TCapabilitiesArray CCapabilityParseVisitor::GetCapabilities()
+	{
+	TCapabilitiesArray array = iCapabilities;
+	iCapabilities.Reset(); // since we're transferring ownership
+	return array;  
+	}
+
+/**
+Destructor
+@publishedPartner
+@released
+*/
+CCapabilityParseVisitor::~CCapabilityParseVisitor()
+	{
+	// we may not have transferred ownership of capabilities, so release all if non-NULL
+	iCapabilities.DeleteAll();
+	}
+
+EXPORT_C CCapabilityVisitor::CCapabilityVisitor(): iCapabilityPtr(NULL, 0)
+	{
+	}
+/**
+Checks for valid capabilities within a signalling message
+@internalTechnology
+@param aCapabilityPDUDomain the message
+*/
+EXPORT_C void CCapabilityVisitor::Process(TDes8& aCapabilityPDUDomain)
+	{
+	// walk through structure and allow visitor to operate on each cap
+	TInt index =0;
+	TInt capsLen = aCapabilityPDUDomain.Length()-KAvdtpServiceCapabilitiesHeaderLen;
+	while(index <= capsLen)
+		{
+		TPtrC8 hdr;
+		hdr.Set(aCapabilityPDUDomain.Mid(index, KAvdtpServiceCapabilitiesHeaderLen));
+		
+		TAvdtpServiceCategory cat = static_cast<TAvdtpServiceCategory>(hdr[0]);
+		TInt losc = static_cast<TInt>(hdr[1]); // (losc is Length of Service Capability)
+		
+		// check for badly formed capabilities
+		if (losc<=aCapabilityPDUDomain.Length()-index-KAvdtpServiceCapabilitiesHeaderLen)
+			{
+			iCapabilityPtr.Set(aCapabilityPDUDomain.MidTPtr(index, KAvdtpServiceCapabilitiesHeaderLen + losc));
+			iCapabilityPayload.Set(aCapabilityPDUDomain.Mid(index+KAvdtpServiceCapabilitiesHeaderLen, losc));
+
+			TBool repeat = Capability(cat);
+			
+			if (!repeat)
+				{
+				break;
+				}
+			else
+				{
+				/*
+				We need to delete the end of iCapabilityPtr that the derived class has chomped
+				
+				We are currently processing capability n
+				 _______________________________________________________
+				|  Cap 0	|  Cap n	| Cap n chomped	|   Cap n+1		|
+				|  - n-1	|			| data			|   - end		|
+				|___________|___________|_______________|_______________|
+					index > ^			^ < index + ptr.Length 
+							 <--------->
+							  ptr.Length
+							 <------------------------->
+								ptr.MaxLength
+								
+				We need to delete the chomped data, which has a start position of
+				index + ptr.Length, and a length of ptr.MaxLength - ptr.Length
+				*/
+				
+				TUint chompedLength = iCapabilityPtr.MaxLength() - iCapabilityPtr.Length();
+				
+				aCapabilityPDUDomain.Delete(index + iCapabilityPtr.Length(), chompedLength);
+				index+=iCapabilityPtr.Length();
+				capsLen -= chompedLength;
+				}
+			}
+		else
+			{
+			// abandon remainder
+			break;
+			}
+		}		
+	}
+
+EXPORT_C const TDesC8& CCapabilityVisitor::CapabilityPayload()
+	{
+	return iCapabilityPayload;
+	}
+
+EXPORT_C TDes8& CCapabilityVisitor::CapabilityDes()
+	{
+	return iCapabilityPtr;
+	}
+
+/**
+Converts an enumeration value corresponding to an AVDTP Signalling error
+into a system-wide error code.
+
+The AVDTP Signalling error range: -18172 to -18045 (inclusive) 
+@publishedPartner
+@released
+@param aAvdtpError The locally defined error value.
+@return System-wide error code within the AVDTP Signalling error space; -18172 to -18045 (inclusive).
+*/	
+EXPORT_C /*static*/ TInt SymbianBluetoothAV::ConvertToSymbianError::AvdtpError(SymbianBluetoothAV::TAvdtpSignallingErrorCode aAvdtpError)
+	{
+	return DoConvertError(aAvdtpError);
+	}
+	
+/**
+Converts an enumeration value corresponding to a GAVDP Signalling error
+into a system-wide error code.
+
+The GAVDP Signalling error range: -18236 to -18173 (inclusive) 
+@publishedPartner
+@released
+@param aGavdpError The locally defined error value.
+@return System-wide error code within the GAVDP Signalling error space; -18236 to -18173 (inclusive).
+*/	
+EXPORT_C /*static*/ TInt SymbianBluetoothAV::ConvertToSymbianError::GavdpError(TGavdpSignallingErrorCode aGavdpError)
+	{
+	return DoConvertError(aGavdpError);
+	}
+	
+/**
+Converts an enumeration value corresponding to an A2DP Signalling error
+into a system-wide error code.  The A2DP Signalling error codes are mapped
+into the concrete profile error code range which is shared with other profiles that sit on top of the GAVDP, such as VDP.  
+
+Mappings into this range of values are done locally by each profile and will typically cover 
+the same subsets of the error code space.  
+These error codes are therefore	not globally unique and any value within this range 
+requires the context of the profile it originated from in order for it to be fully defined.
+
+The concrete profile signalling error range: -18300 to -18237 (inclusive) 
+@publishedPartner
+@released
+@param aA2dpError The locally defined error value.
+@return System-wide error code within the concrete profile error space;  -18300 to -18237 (inclusive).
+*/	
+EXPORT_C /*static*/ TInt SymbianBluetoothAV::ConvertToSymbianError::A2dpError(TA2dpSignallingErrorCode aA2dpError)
+	{
+	return DoConvertError(aA2dpError);
+	}
+
+/**
+Converts an enumeration value corresponding to a VDP Signalling error
+into a system-wide error code.  The VDP Signalling error codes are mapped
+into the concrete profile error code range which is shared with other profiles that sit on top of the GAVDP, such as A2DP.  
+
+Mappings into this range of values are done locally by each profile and will typically cover 
+the same subsets of the error code space.  
+These error codes are therefore	not globally unique and any value within this range 
+requires the context of the profile it originated from in order for it to be fully defined.
+
+The concrete profile signalling error range: -18300 to -18237 (inclusive) 
+@publishedPartner
+@released
+@param aVdpError The locally defined error value.
+@return System-wide error code within the concrete profile error space; -18300 to -18237 (inclusive) .
+*/	
+EXPORT_C /*static*/ TInt SymbianBluetoothAV::ConvertToSymbianError::VdpError(TVdpSignallingErrorCode aVdpError)
+	{
+	return DoConvertError(aVdpError);
+	}
+
+/**
+Takes the local signalling error code (which is a relative offset from the Bluetooth Audio/Visual base signalling 
+error code) of any A/V profile type and calculates the corresponding system-wide error code.  This function is called by 
+a profile specific error conversion function.  For full documentation of what the error code corresponds to 
+refer to the relevant profile's conversion function.  
+
+A Bluetooth A/V Signalling error code will exist within the range -18045 to -18300 (inclusive).
+@publishedPartner
+@released
+@param aError The value of the error enumeration object.
+@return A standard Symbian system-wide error code; -18045 to -18300 (inclusive).
+
+*/
+/*static*/ TInt SymbianBluetoothAV::ConvertToSymbianError::DoConvertError(TBluetoothAvDistributionError aAVError)
+	{
+	// check not already in correct range
+	return KErrAvdtpSignallingErrorBase-static_cast<TInt>(aAVError);
+	}
+