diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/avdtp/avdtpMuxChannel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/btstack/avdtp/avdtpMuxChannel.h Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,211 @@ +// 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: +// + +#ifndef AVDTPMUXCHANNEL_H +#define AVDTPMUXCHANNEL_H + +#include "avdtpTransportChannel.h" +#include "avdtpTransportSession.h" +#include "avdtpMessage.h" + +class CTransportSession; +class CMuxChannel; + + +#ifdef _OOM_TEST +static const TInt KMuxSendInitial = 500; +static const TInt KMuxSendPeriod = 500; +#else +static const TInt KMuxSendInitial = 2000000; +static const TInt KMuxSendPeriod = 2000000; +#endif +// this constant already allows for AL header +static const TInt KMaxMuxedPacketLength = 335;// 339 for DH5 - 4 byte L2CAP +static const TInt KMuxedPacketLengthReadyToSend = 100; // for 3 slot use +static const TInt KALHeaderLength = 1; // we only support one byte (no AVDTP jumbograms) +static const TInt KALHeaderTSIDOffset = 5; +static const TInt KALHeaderFOffset = 2; +static const TInt KALHeaderLCODE_MSBOffset = 1; +static const TInt KALHeaderLCODE_LSBOffset = 0; + + +NONSHARABLE_CLASS(CAvdtpOutboundMuxedMessage) : public CAvdtpMessage + { + public: + enum TMuxedMessageOperation + { + ENoMemory, + EReadyToSendPacketAdded, + EReadyToSendPacketNotConsumed, + EPacketAdded, + }; + + static CAvdtpOutboundMuxedMessage* NewL(); + virtual TInt NewData(TUint aCount); + TMuxedMessageOperation TryToAddPacket(TTSID aTSID, RMBufChain& aChain); + TInt Reset(); + +private: + TInt AddHeader(TTSID aTSID, TInt aPacketLen); + /* + */ + +/* + class starts with blank muxpacket + sessions write into channel + muxchannel can put into send pool for that session + muxchannelCB fetches stuff off pools into packet + +OR! + class starts with blank muxpacket + sessions request to send (with a packet length?) + channel invites send + MuxTC can base sends on length (and above rules) + +*/ + + // easier if send pools are in channels as then muxchannel can + // "see" at any time what size packets it has and can squeeze into an ALPDU + +private: + }; + + +NONSHARABLE_CLASS(CAvdtpInboundMuxedMessage) : public CAvdtpMessage + { +public: + static CAvdtpInboundMuxedMessage* NewL(CMuxChannel& aMuxChannel); + virtual TInt NewData(TUint aCount); // should cause self-parsing + + void Reset(); + +private: + CAvdtpInboundMuxedMessage(CMuxChannel& aMuxChannel); +private: + CMuxChannel& iMuxChannel; // to callback when mux message parsed + }; + + +/* +helper for cmux channel to iterate over *all* of its sessions +it keeps its sessions in separate arrays cos of rom/ram/runtime savings +(e.g. it has to knwo the session type, but that would incur virtual function calls) + +We prefer arrays so that inbound data can more quickly be put onto array rather than iter to find TSID + +*/ +// templates version (armv5 urel is only ~160 bytes bigger than a non-template version + +template +class TSessionIterator + { +public: + TSessionIterator(const TArray< const TArray >& aArrayOfArrays); + + const T& operator++(TInt aPostIncrementDummy); + + operator TBool(); // conversion operator to make iterator just like a normal one + void Reset(); +private: + void DoIncrement(); + const TArray< const TArray > iArrays; + TInt iArray; // which array we're at + TInt iArrayIndex;// the index we're at in the array + TBool iFinished; + }; + + +NONSHARABLE_CLASS(CMuxChannel) : public CTransportChannel + { +public: + static CMuxChannel* NewL(CAvdtpProtocol& aProtocol, const TBTDevAddr& aRemoteDevice, + TTCID aRemotelyAssignedTCID); + +// management path + virtual TInt AttachTransportSession(CUserPlaneTransportSession& aSession, TAvdtpTransportSessionType aType); + virtual void DetachTransportSession(CUserPlaneTransportSession& aSession, TAvdtpTransportSessionType aType); + virtual TBool CouldAttachSession(const TAvdtpSockAddr& aAddr); + virtual TTCID TCID() const; + CServProviderBase* ObtainSAP(); + void ActiveMultiplexer(); +// send path + virtual TUint SendPacket(TTSID aTSID, RMBufChain& aPacket); +// receive path + TInt GetData(RMBufChain& aRxBuffer); + virtual void TransportSessionBlocked(TAvdtpTransportSessionType aSession, TBool aBlocked); + +//... interface from inbound packet +// TInt SessionDataReceived(TTSID aTSID, RMBufChain& aChain); + + ~CMuxChannel(); + +private: + CMuxChannel(CAvdtpProtocol& aProtocol, const TBTDevAddr& aRemoteDevice); + + static TInt MuxSendIntervalCb(TAny* aCMuxChannel); + void CheckForClose(); + TUint DoSend(); + +private: +// interesting stuff from l2cap + virtual void NewData(TUint aCount); // forwards to inbound mux message + virtual void Error(TInt aError,TUint aOperationMask=EErrorAllOperations); + virtual void Disconnect(); + virtual void CanSend(); + + void ConstructL(TTCID aRemotelyAssignedTCID); + +private: + // receive path + struct TUserPlaneTransportSessionState + { + inline TUserPlaneTransportSessionState(CUserPlaneTransportSession& aSession); + + CUserPlaneTransportSession& iSession; + TBool iIsBlocked; + + }; + + RArray iMediaSessions; + RArray iReportingSessions; + RArray iRecoverySessions; // recall not from same streams as other sessions + + RArray > iSessions; + +// for now shared by all the same-typed sessions +// RPacketPool iMediaReceivePool; +// RPacketPool iReportingReceivePool; +// RPacketPool iRecoveryReceivePool; + + CPeriodic* iMuxSendTimer; + + CAvdtpInboundMuxedMessage* iInboundMessage; + CAvdtpOutboundMuxedMessage* iOutboundMessage; +#ifdef SESSION_ITERATOR_CONCRETE + TSessionIterator iIter; +#else + TSessionIterator iIter; +#endif + // could have send iterator? + }; + +inline CMuxChannel::TUserPlaneTransportSessionState::TUserPlaneTransportSessionState( + CUserPlaneTransportSession& aSession) +: iSession(aSession) + { + } + + +#endif //AVDTPMUXCHANNEL_H