|
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 // |
|
15 |
|
16 #ifndef AVDTPMUXCHANNEL_H |
|
17 #define AVDTPMUXCHANNEL_H |
|
18 |
|
19 #include "avdtpTransportChannel.h" |
|
20 #include "avdtpTransportSession.h" |
|
21 #include "avdtpMessage.h" |
|
22 |
|
23 class CTransportSession; |
|
24 class CMuxChannel; |
|
25 |
|
26 |
|
27 #ifdef _OOM_TEST |
|
28 static const TInt KMuxSendInitial = 500; |
|
29 static const TInt KMuxSendPeriod = 500; |
|
30 #else |
|
31 static const TInt KMuxSendInitial = 2000000; |
|
32 static const TInt KMuxSendPeriod = 2000000; |
|
33 #endif |
|
34 // this constant already allows for AL header |
|
35 static const TInt KMaxMuxedPacketLength = 335;// 339 for DH5 - 4 byte L2CAP |
|
36 static const TInt KMuxedPacketLengthReadyToSend = 100; // for 3 slot use |
|
37 static const TInt KALHeaderLength = 1; // we only support one byte (no AVDTP jumbograms) |
|
38 static const TInt KALHeaderTSIDOffset = 5; |
|
39 static const TInt KALHeaderFOffset = 2; |
|
40 static const TInt KALHeaderLCODE_MSBOffset = 1; |
|
41 static const TInt KALHeaderLCODE_LSBOffset = 0; |
|
42 |
|
43 |
|
44 NONSHARABLE_CLASS(CAvdtpOutboundMuxedMessage) : public CAvdtpMessage |
|
45 { |
|
46 public: |
|
47 enum TMuxedMessageOperation |
|
48 { |
|
49 ENoMemory, |
|
50 EReadyToSendPacketAdded, |
|
51 EReadyToSendPacketNotConsumed, |
|
52 EPacketAdded, |
|
53 }; |
|
54 |
|
55 static CAvdtpOutboundMuxedMessage* NewL(); |
|
56 virtual TInt NewData(TUint aCount); |
|
57 TMuxedMessageOperation TryToAddPacket(TTSID aTSID, RMBufChain& aChain); |
|
58 TInt Reset(); |
|
59 |
|
60 private: |
|
61 TInt AddHeader(TTSID aTSID, TInt aPacketLen); |
|
62 /* |
|
63 */ |
|
64 |
|
65 /* |
|
66 class starts with blank muxpacket |
|
67 sessions write into channel |
|
68 muxchannel can put into send pool for that session |
|
69 muxchannelCB fetches stuff off pools into packet |
|
70 |
|
71 OR! |
|
72 class starts with blank muxpacket |
|
73 sessions request to send (with a packet length?) |
|
74 channel invites send |
|
75 MuxTC can base sends on length (and above rules) |
|
76 |
|
77 */ |
|
78 |
|
79 // easier if send pools are in channels as then muxchannel can |
|
80 // "see" at any time what size packets it has and can squeeze into an ALPDU |
|
81 |
|
82 private: |
|
83 }; |
|
84 |
|
85 |
|
86 NONSHARABLE_CLASS(CAvdtpInboundMuxedMessage) : public CAvdtpMessage |
|
87 { |
|
88 public: |
|
89 static CAvdtpInboundMuxedMessage* NewL(CMuxChannel& aMuxChannel); |
|
90 virtual TInt NewData(TUint aCount); // should cause self-parsing |
|
91 |
|
92 void Reset(); |
|
93 |
|
94 private: |
|
95 CAvdtpInboundMuxedMessage(CMuxChannel& aMuxChannel); |
|
96 private: |
|
97 CMuxChannel& iMuxChannel; // to callback when mux message parsed |
|
98 }; |
|
99 |
|
100 |
|
101 /* |
|
102 helper for cmux channel to iterate over *all* of its sessions |
|
103 it keeps its sessions in separate arrays cos of rom/ram/runtime savings |
|
104 (e.g. it has to knwo the session type, but that would incur virtual function calls) |
|
105 |
|
106 We prefer arrays so that inbound data can more quickly be put onto array rather than iter to find TSID |
|
107 |
|
108 */ |
|
109 // templates version (armv5 urel is only ~160 bytes bigger than a non-template version |
|
110 |
|
111 template <class T> |
|
112 class TSessionIterator |
|
113 { |
|
114 public: |
|
115 TSessionIterator(const TArray< const TArray<T> >& aArrayOfArrays); |
|
116 |
|
117 const T& operator++(TInt aPostIncrementDummy); |
|
118 |
|
119 operator TBool(); // conversion operator to make iterator just like a normal one |
|
120 void Reset(); |
|
121 private: |
|
122 void DoIncrement(); |
|
123 const TArray< const TArray<T> > iArrays; |
|
124 TInt iArray; // which array we're at |
|
125 TInt iArrayIndex;// the index we're at in the array |
|
126 TBool iFinished; |
|
127 }; |
|
128 |
|
129 |
|
130 NONSHARABLE_CLASS(CMuxChannel) : public CTransportChannel |
|
131 { |
|
132 public: |
|
133 static CMuxChannel* NewL(CAvdtpProtocol& aProtocol, const TBTDevAddr& aRemoteDevice, |
|
134 TTCID aRemotelyAssignedTCID); |
|
135 |
|
136 // management path |
|
137 virtual TInt AttachTransportSession(CUserPlaneTransportSession& aSession, TAvdtpTransportSessionType aType); |
|
138 virtual void DetachTransportSession(CUserPlaneTransportSession& aSession, TAvdtpTransportSessionType aType); |
|
139 virtual TBool CouldAttachSession(const TAvdtpSockAddr& aAddr); |
|
140 virtual TTCID TCID() const; |
|
141 CServProviderBase* ObtainSAP(); |
|
142 void ActiveMultiplexer(); |
|
143 // send path |
|
144 virtual TUint SendPacket(TTSID aTSID, RMBufChain& aPacket); |
|
145 // receive path |
|
146 TInt GetData(RMBufChain& aRxBuffer); |
|
147 virtual void TransportSessionBlocked(TAvdtpTransportSessionType aSession, TBool aBlocked); |
|
148 |
|
149 //... interface from inbound packet |
|
150 // TInt SessionDataReceived(TTSID aTSID, RMBufChain& aChain); |
|
151 |
|
152 ~CMuxChannel(); |
|
153 |
|
154 private: |
|
155 CMuxChannel(CAvdtpProtocol& aProtocol, const TBTDevAddr& aRemoteDevice); |
|
156 |
|
157 static TInt MuxSendIntervalCb(TAny* aCMuxChannel); |
|
158 void CheckForClose(); |
|
159 TUint DoSend(); |
|
160 |
|
161 private: |
|
162 // interesting stuff from l2cap |
|
163 virtual void NewData(TUint aCount); // forwards to inbound mux message |
|
164 virtual void Error(TInt aError,TUint aOperationMask=EErrorAllOperations); |
|
165 virtual void Disconnect(); |
|
166 virtual void CanSend(); |
|
167 |
|
168 void ConstructL(TTCID aRemotelyAssignedTCID); |
|
169 |
|
170 private: |
|
171 // receive path |
|
172 struct TUserPlaneTransportSessionState |
|
173 { |
|
174 inline TUserPlaneTransportSessionState(CUserPlaneTransportSession& aSession); |
|
175 |
|
176 CUserPlaneTransportSession& iSession; |
|
177 TBool iIsBlocked; |
|
178 |
|
179 }; |
|
180 |
|
181 RArray<TUserPlaneTransportSessionState> iMediaSessions; |
|
182 RArray<TUserPlaneTransportSessionState> iReportingSessions; |
|
183 RArray<TUserPlaneTransportSessionState> iRecoverySessions; // recall not from same streams as other sessions |
|
184 |
|
185 RArray<const TArray<TUserPlaneTransportSessionState> > iSessions; |
|
186 |
|
187 // for now shared by all the same-typed sessions |
|
188 // RPacketPool iMediaReceivePool; |
|
189 // RPacketPool iReportingReceivePool; |
|
190 // RPacketPool iRecoveryReceivePool; |
|
191 |
|
192 CPeriodic* iMuxSendTimer; |
|
193 |
|
194 CAvdtpInboundMuxedMessage* iInboundMessage; |
|
195 CAvdtpOutboundMuxedMessage* iOutboundMessage; |
|
196 #ifdef SESSION_ITERATOR_CONCRETE |
|
197 TSessionIterator iIter; |
|
198 #else |
|
199 TSessionIterator<TUserPlaneTransportSessionState> iIter; |
|
200 #endif |
|
201 // could have send iterator? |
|
202 }; |
|
203 |
|
204 inline CMuxChannel::TUserPlaneTransportSessionState::TUserPlaneTransportSessionState( |
|
205 CUserPlaneTransportSession& aSession) |
|
206 : iSession(aSession) |
|
207 { |
|
208 } |
|
209 |
|
210 |
|
211 #endif //AVDTPMUXCHANNEL_H |