--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/avdtp/avdtpSignallingChannel.h Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,326 @@
+// 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:
+// Defines the avdtp signalling channel
+// Signalling channel - not a transport channel by type, but called "signalling channel" as it maps very
+// clearly onto that defined in the AVDTP specification
+// There is at most one signalling channel for a remote device. Many applications can use the signalling
+// channel via the multiplexing of signalling sessions.
+// The signalling channel is given a logical channel (l2cap shannel) to run on from the logical channel factory
+// The signalling channels responsibilities are:
+// - offer signalling protocol send primitives
+// - offer incoming signalling protocol indications to all the attached signalling sessions
+// - provide a mechanism to patch up deficiencies in the specification (eg providing SEIDs in protocol confirms
+// to signalling sessions that call send primitives
+// All signalling sessions on a listening signalling channel become connected once the listening channel is
+// connected.
+// All signalling sessions on a listening signalling channel are transfered to the new connected
+// signalling channel upon the completion of an active open. The listening signalling channel is
+// left to continue listening. New sessions attached to it will not be connected to the existing
+// channel.
+// The signalling channel does not parse incoming messages. Incoming data from the logical channel is
+// given to the incoming message. The incoming message builds and parses itself.
+// The signalling message then calls the Handle methods on the signalling channel which liases with the
+// signalling sessions.
+//
+//
+
+#ifndef AVDTPSIGNALLINGCHANNEL_H
+#define AVDTPSIGNALLINGCHANNEL_H
+
+#include <es_prot.h>
+#include "avdtpSignallingMessages.h"
+#include "avdtpLogicalChannelFactory.h"
+#include "avdtpSEPCache.h"
+#include "avdtpAllocators.h"
+
+class CAvdtpProtocol;
+class XAvdtpSignalReceiver;
+class RMBufChain;
+class CSignallingTransaction;
+
+static const TInt KAvdtpReleaseAcceptPriority = CActive::EPriorityHigh;
+#ifdef _OOM_TEST
+static const TInt KAvdtpSignallingChannelIdleTimeout = 800;
+#else
+static const TInt KAvdtpSignallingChannelIdleTimeout = 3000000; // 3s
+#endif
+
+NONSHARABLE_CLASS(CSignallingChannel) : public CBase, public MSocketNotify, public XLogicalChannelFactoryClient
+/**
+Relatively stateless entity - driven mainly by GC
+Provides primitives that accord with spec, but parameterised and initiated by
+GC and Avdtp[Signalling]SAPs.
+*/
+ {
+friend class CAvdtpProtocol; // for queing
+friend class CAvdtpInboundSignallingMessage; //for SendingRejects
+
+public:
+ static CSignallingChannel* NewL(CAvdtpProtocol& aProtocol,
+ CLogicalChannelFactory& aChannelFactory,
+ const TBTDevAddr& aRemoteAddr);
+
+ static CSignallingChannel* NewLC(CAvdtpProtocol& aProtocol,
+ CLogicalChannelFactory& aChannelFactory,
+ const TBTDevAddr& aRemoteAddr);
+
+ TInt AttachSignallingUser(XAvdtpSignalReceiver& aReceiver);
+ void DetachSignallingUser(XAvdtpSignalReceiver& aReceiver);
+ void CancelTransactions(XAvdtpSignalReceiver& aUser);
+ void RemoveTransaction(CSignallingTransaction& aTransaction);
+
+ TBTDevAddr RemoteAddress(); // intentional signature
+ inline TBool IsListening() const;
+
+// for this remote (this class models "Connection-local" stuff in spec too)
+ inline TTCIDManager& TCIDManager();
+ inline TTSIDManager& TSIDManager();
+// Service Primitives
+
+// Signalling sessions provide a reference to themselves so that we can do some muxing
+// their details can form the basis of the AVDTP TransactionLabel.
+// as we can bind the caller (SAP) address with the TransLabel
+// see CSignallingTransaction
+// we can't do away with Attaching/Detaching of SAPs as that is required
+// to signal when this object is ready
+
+// INT primitives
+ TInt SendDiscoverSEPs(XAvdtpSignalReceiver& aReceiver);
+ TInt SendGetCapabilities(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID);
+ TInt SendSetConfiguration(XAvdtpSignalReceiver& aReceiver, TSEID aINTSEID, TSEID aACPSEID, const RBuf8& aConfiguration);
+ TInt SendRelease(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID);
+ TInt SendAbort(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID);
+ TInt SendStartStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID);
+ TInt SendSuspendStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID);
+ TInt SendSecurityControl(XAvdtpSignalReceiver& aReceiver,
+ TSEID aACPSEID,
+ const TDesC8& aSecurityData);
+ TInt SendReconfigure(XAvdtpSignalReceiver& aReceiver,
+ TSEID aACPSEID,
+ const RBuf8& aConfiguration);
+
+ TInt SendOpenStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID);
+
+
+// Upcall primitives from packet parsing - bit like XAvdtpSignalReceiver, but more params
+
+ // confirms
+ void DiscoverConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const TAvdtpInternalDiscoverConfirm* const aConfirm);
+ void GetCapsConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const HBufC8* aCapsDataAsProtocol = NULL);
+ void SetConfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, TAvdtpServiceCategory aErrorCategory);
+ void ReleaseConfirm(TAvdtpTransactionLabel aLabel, TInt aResult);
+ void GetConfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult);
+ void ReconfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, TAvdtpServiceCategory aErrorCategory);
+ void OpenConfirm(TAvdtpTransactionLabel aLabel, TInt aResult);
+ void StartConfirm(TAvdtpTransactionLabel aLabel, TInt aResult);
+ void AbortConfirm(TAvdtpTransactionLabel aLabel); // no error
+ void SuspendConfirm(TAvdtpTransactionLabel aLabel, TInt aResult);
+ void SecurityControlConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const TDesC8& aResponseData);
+
+ // indications
+ void DiscoverIndication(TAvdtpTransactionLabel aLabel);
+ void GetCapsIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID);
+ void SetConfigIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID,
+ TSEID aINTSEID, RBuf8& aConfigData);
+ void GetConfigIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID);
+ void ReconfigIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID, RBuf8& aConfigData);
+ void OpenIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID);
+ void StartIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID);
+ void ReleaseIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID);
+ void SuspendIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID);
+ void AbortIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID);
+ void SecurityControlIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID, const HBufC8* aSecurityData);
+
+
+ TInt SendSetConfigurationAccept(TAvdtpTransactionLabel aLabel);
+ TInt SendSetConfigurationReject(TAvdtpTransactionLabel aLabel, TBluetoothAvDistributionError aResult,
+ TAvdtpServiceCategory aCategory);
+
+ TInt SendReconfigureAccept(TAvdtpTransactionLabel aLabel);
+ TInt SendReconfigureReject(TAvdtpTransactionLabel aLabel, TBluetoothAvDistributionError aResult,
+ TAvdtpServiceCategory aCategory);
+
+ TInt SendStartAccept(TAvdtpTransactionLabel aLabel);
+ TInt SendStartReject(TAvdtpTransactionLabel aLabel,TBluetoothAvDistributionError aResult, TSEID aBadSEID);
+ TInt SendSuspendAccept(TAvdtpTransactionLabel aLabel);
+ TInt SendSuspendReject(TAvdtpTransactionLabel aLabel,TBluetoothAvDistributionError aResult, TSEID aBadSEID);
+
+ TInt SendSecurityControlAccept(TAvdtpTransactionLabel aLabel, const TDesC8* aOptionalData = NULL);
+ TInt SendSecurityControlReject(TAvdtpTransactionLabel aLabel, TBluetoothAvDistributionError aResult);
+
+ TInt SendReleaseAccept(TAvdtpTransactionLabel aLabel);
+
+// non-spec stuff
+ TInt GetData(RMBufChain& aData, TUint aOptions, TSockAddr* anAddr=NULL);
+ virtual void NewData(TUint aCount);
+
+// async stuff
+ void StartTryToSendCallback();
+ void CancelTryToSendCallback();
+ static TInt TryToSendCallback(TAny *aSigCh); //the static one we have to register
+ TInt TryToSendCallback(); //on this Signalling Channel
+private:
+// from MSocketNotify - transport (rather than packet) upcalls
+ virtual void CanSend();
+ virtual void ConnectComplete();
+ virtual void ConnectComplete(const TDesC8& aConnectData);
+ virtual void ConnectComplete(CServProviderBase& aSSP);
+ virtual void ConnectComplete(CServProviderBase& aSSP,const TDesC8& aConnectData);
+ virtual void CanClose(TDelete aDelete=EDelete);
+ virtual void CanClose(const TDesC8& aDisconnectData,TDelete aDelete=EDelete);
+ virtual void Disconnect(void);
+ virtual void Disconnect(TDesC8& aDisconnectData);
+ virtual void IoctlComplete(TDesC8 *aBuf);
+ virtual void Error(TInt anError,TUint anOperationMask=EErrorAllOperations);
+ virtual void NoBearer(const TDesC8& /*aConnectionInfo*/);
+ virtual void Bearer(const TDesC8& aConnectionInfo);
+ static TInt TryToClose(TAny* aSignallingChannel);
+
+private:
+// from MLogicalChannelFactoryClient
+ void LogicalChannelFactoryRequestComplete(TLogicalChannelFactoryTicket aTicket, TInt aErr);
+private:
+ CSignallingChannel(CAvdtpProtocol& aProtocol, CLogicalChannelFactory& aChannelFactory, const TBTDevAddr& aRemoteAddr);
+ TInt EnqueueMessage(CSignallingTransaction& aTok);
+ void ConstructL();
+ void RemoveTransactions(XAvdtpSignalReceiver& aUser);
+ void PacketSent(CSignallingTransaction& aToken);
+ void ObtainMTU();
+ void ConfigConfirm(TAvdtpTransactionLabel aLabel,
+ TInt aResult,
+ TAvdtpServiceCategory aCategory,
+ TBool aReconfigure);
+
+ CSignallingTransaction* PrepareSignallingCommand(XAvdtpSignalReceiver& aReceiver, TAvdtpMessage aMessage);
+ CSignallingTransaction* PrepareSignallingResponse(TAvdtpMessageType aMessageType, TAvdtpMessage aMessage, TAvdtpTransactionLabel aLabel);
+ CSignallingTransaction* PrepareSignallingPacket(TAvdtpMessageType aMessageType, TAvdtpMessage aMessage);
+
+
+ CSignallingTransaction* FindTransaction(TAvdtpTransactionLabel aLabel);
+ void HandleSignallingCommand(CAvdtpSignallingMessage& aSigMessage);
+
+ void CheckOutboundQueue();
+ void ServiceOutboundQueue();
+
+ inline void SetBlocked(TBool aBlocked);
+ inline TBool Blocked() const;
+
+ ~CSignallingChannel(); //only this can delete this
+ inline const TDblQue<XAvdtpSignalReceiver>& Users() const;
+
+// PDU operations not available for external use
+ TInt SendAccept(TAvdtpTransactionLabel aLabel, TAvdtpMessage aMessage, const TDesC8* aOptionalData = NULL);
+
+ TInt SendReject(TAvdtpTransactionLabel aLabel,
+ TAvdtpMessage aMessage,
+ TBluetoothAvDistributionError aError,
+ const TDesC8* aRejectionData = NULL);
+ void QueIdleTimer();
+ void ErrorPermanentUsers(TInt aError);
+ void ErrorServiceRequesters(TInt aError);
+ TBool CheckSignal(const CSignallingTransaction& aToken, TAvdtpMessage aSignal) const;
+ void CancelIdleTimer();
+ TBool IsIdle() const;
+ void IdledD();
+
+private:
+ CAvdtpProtocol& iProtocol;
+ CLogicalChannelFactory& iLogicalChannelFactory;
+ CServProviderBase* iBearer;
+ TDblQueLink iProtocolQLink;
+ TDblQue<XAvdtpSignalReceiver> iPermanentUsers;
+ TDblQue<CSignallingTransaction> iTransactions;
+ TInt iBearerMTU;
+
+ /**
+ this value is either the intended remote or the actual one
+ whereas RemoteAddress() returns 0 if the connection is not actually in place
+ */
+ TBTDevAddr iRemoteAddress;
+ TTransactionLabelManager iLabelGen;
+
+ /**
+ There is always one and only one incoming message [can be empty]
+ */
+ CAvdtpInboundSignallingMessage iInboundMessage;
+
+ /**
+ Messages being prepared by their Signalling Sessions.
+ NB: this que will need to be purged of messages owned by a SS
+ when it detaches (do we want to limit how many messages a SS can
+ be preparing at once?)
+ */
+ TDblQue<CAvdtpOutboundSignallingMessage> iDraftMessages;
+
+ /**
+ Messages sitting in our outbound queue
+ */
+ TDblQue<CAvdtpOutboundSignallingMessage> iQueuedMessages;
+
+ /**
+ The fragments which have been prepared from a message plucked
+ off the outbound que (and fragmented according to the MTU of
+ the L2CAP channel). Only flushed if an ABORT appears in the
+ queue for the _same_SEP_ [subtle, see AVDTP spec pp62].
+ */
+ RMBufChain iOutgoingSignallingMessage;
+ TBool iMoreFrags;
+ CSignallingTransaction* iCurrentTransaction;
+
+ TBool iBlocked;
+
+ CAsyncCallBack* iTryToSendCallback; // sig msgs sent asynchronously
+
+// these managers are "Connection-local" in spec, hence this class owns them
+ TTCIDManager iTCIDManager;
+ TTSIDManager iTSIDManager;
+
+ TDeltaTimerEntry iIdleTimerEntry; //< Disconnection idle timer
+ TBool iIdleTimerActive; //< Is Idle timer running.
+
+ TLogicalChannelFactoryTicket iLogicalChannelRequest; // for passive request for now
+ };
+
+inline TTCIDManager& CSignallingChannel::TCIDManager()
+ {
+ return iTCIDManager;
+ }
+
+inline TTSIDManager& CSignallingChannel::TSIDManager()
+ {
+ return iTSIDManager;
+ }
+
+inline TBool CSignallingChannel::Blocked() const
+ {
+ return iBlocked;
+ }
+
+inline void CSignallingChannel::SetBlocked(TBool aBlocked)
+ {
+ iBlocked=aBlocked;
+ }
+
+inline const TDblQue<XAvdtpSignalReceiver>& CSignallingChannel::Users() const
+ {
+ return iPermanentUsers;
+ }
+
+inline TBool CSignallingChannel::IsListening() const
+ {
+ return iRemoteAddress==TBTDevAddr(0);
+ }
+
+#endif //AVDTPSIGNALLINGCHANNEL_H
+