|
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 // Defines the avdtp signalling channel |
|
15 // Signalling channel - not a transport channel by type, but called "signalling channel" as it maps very |
|
16 // clearly onto that defined in the AVDTP specification |
|
17 // There is at most one signalling channel for a remote device. Many applications can use the signalling |
|
18 // channel via the multiplexing of signalling sessions. |
|
19 // The signalling channel is given a logical channel (l2cap shannel) to run on from the logical channel factory |
|
20 // The signalling channels responsibilities are: |
|
21 // - offer signalling protocol send primitives |
|
22 // - offer incoming signalling protocol indications to all the attached signalling sessions |
|
23 // - provide a mechanism to patch up deficiencies in the specification (eg providing SEIDs in protocol confirms |
|
24 // to signalling sessions that call send primitives |
|
25 // All signalling sessions on a listening signalling channel become connected once the listening channel is |
|
26 // connected. |
|
27 // All signalling sessions on a listening signalling channel are transfered to the new connected |
|
28 // signalling channel upon the completion of an active open. The listening signalling channel is |
|
29 // left to continue listening. New sessions attached to it will not be connected to the existing |
|
30 // channel. |
|
31 // The signalling channel does not parse incoming messages. Incoming data from the logical channel is |
|
32 // given to the incoming message. The incoming message builds and parses itself. |
|
33 // The signalling message then calls the Handle methods on the signalling channel which liases with the |
|
34 // signalling sessions. |
|
35 // |
|
36 // |
|
37 |
|
38 #ifndef AVDTPSIGNALLINGCHANNEL_H |
|
39 #define AVDTPSIGNALLINGCHANNEL_H |
|
40 |
|
41 #include <es_prot.h> |
|
42 #include "avdtpSignallingMessages.h" |
|
43 #include "avdtpLogicalChannelFactory.h" |
|
44 #include "avdtpSEPCache.h" |
|
45 #include "avdtpAllocators.h" |
|
46 |
|
47 class CAvdtpProtocol; |
|
48 class XAvdtpSignalReceiver; |
|
49 class RMBufChain; |
|
50 class CSignallingTransaction; |
|
51 |
|
52 static const TInt KAvdtpReleaseAcceptPriority = CActive::EPriorityHigh; |
|
53 #ifdef _OOM_TEST |
|
54 static const TInt KAvdtpSignallingChannelIdleTimeout = 800; |
|
55 #else |
|
56 static const TInt KAvdtpSignallingChannelIdleTimeout = 3000000; // 3s |
|
57 #endif |
|
58 |
|
59 NONSHARABLE_CLASS(CSignallingChannel) : public CBase, public MSocketNotify, public XLogicalChannelFactoryClient |
|
60 /** |
|
61 Relatively stateless entity - driven mainly by GC |
|
62 Provides primitives that accord with spec, but parameterised and initiated by |
|
63 GC and Avdtp[Signalling]SAPs. |
|
64 */ |
|
65 { |
|
66 friend class CAvdtpProtocol; // for queing |
|
67 friend class CAvdtpInboundSignallingMessage; //for SendingRejects |
|
68 |
|
69 public: |
|
70 static CSignallingChannel* NewL(CAvdtpProtocol& aProtocol, |
|
71 CLogicalChannelFactory& aChannelFactory, |
|
72 const TBTDevAddr& aRemoteAddr); |
|
73 |
|
74 static CSignallingChannel* NewLC(CAvdtpProtocol& aProtocol, |
|
75 CLogicalChannelFactory& aChannelFactory, |
|
76 const TBTDevAddr& aRemoteAddr); |
|
77 |
|
78 TInt AttachSignallingUser(XAvdtpSignalReceiver& aReceiver); |
|
79 void DetachSignallingUser(XAvdtpSignalReceiver& aReceiver); |
|
80 void CancelTransactions(XAvdtpSignalReceiver& aUser); |
|
81 void RemoveTransaction(CSignallingTransaction& aTransaction); |
|
82 |
|
83 TBTDevAddr RemoteAddress(); // intentional signature |
|
84 inline TBool IsListening() const; |
|
85 |
|
86 // for this remote (this class models "Connection-local" stuff in spec too) |
|
87 inline TTCIDManager& TCIDManager(); |
|
88 inline TTSIDManager& TSIDManager(); |
|
89 // Service Primitives |
|
90 |
|
91 // Signalling sessions provide a reference to themselves so that we can do some muxing |
|
92 // their details can form the basis of the AVDTP TransactionLabel. |
|
93 // as we can bind the caller (SAP) address with the TransLabel |
|
94 // see CSignallingTransaction |
|
95 // we can't do away with Attaching/Detaching of SAPs as that is required |
|
96 // to signal when this object is ready |
|
97 |
|
98 // INT primitives |
|
99 TInt SendDiscoverSEPs(XAvdtpSignalReceiver& aReceiver); |
|
100 TInt SendGetCapabilities(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID); |
|
101 TInt SendSetConfiguration(XAvdtpSignalReceiver& aReceiver, TSEID aINTSEID, TSEID aACPSEID, const RBuf8& aConfiguration); |
|
102 TInt SendRelease(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID); |
|
103 TInt SendAbort(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID); |
|
104 TInt SendStartStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID); |
|
105 TInt SendSuspendStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID); |
|
106 TInt SendSecurityControl(XAvdtpSignalReceiver& aReceiver, |
|
107 TSEID aACPSEID, |
|
108 const TDesC8& aSecurityData); |
|
109 TInt SendReconfigure(XAvdtpSignalReceiver& aReceiver, |
|
110 TSEID aACPSEID, |
|
111 const RBuf8& aConfiguration); |
|
112 |
|
113 TInt SendOpenStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID); |
|
114 |
|
115 |
|
116 // Upcall primitives from packet parsing - bit like XAvdtpSignalReceiver, but more params |
|
117 |
|
118 // confirms |
|
119 void DiscoverConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const TAvdtpInternalDiscoverConfirm* const aConfirm); |
|
120 void GetCapsConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const HBufC8* aCapsDataAsProtocol = NULL); |
|
121 void SetConfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, TAvdtpServiceCategory aErrorCategory); |
|
122 void ReleaseConfirm(TAvdtpTransactionLabel aLabel, TInt aResult); |
|
123 void GetConfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult); |
|
124 void ReconfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, TAvdtpServiceCategory aErrorCategory); |
|
125 void OpenConfirm(TAvdtpTransactionLabel aLabel, TInt aResult); |
|
126 void StartConfirm(TAvdtpTransactionLabel aLabel, TInt aResult); |
|
127 void AbortConfirm(TAvdtpTransactionLabel aLabel); // no error |
|
128 void SuspendConfirm(TAvdtpTransactionLabel aLabel, TInt aResult); |
|
129 void SecurityControlConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const TDesC8& aResponseData); |
|
130 |
|
131 // indications |
|
132 void DiscoverIndication(TAvdtpTransactionLabel aLabel); |
|
133 void GetCapsIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID); |
|
134 void SetConfigIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID, |
|
135 TSEID aINTSEID, RBuf8& aConfigData); |
|
136 void GetConfigIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID); |
|
137 void ReconfigIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID, RBuf8& aConfigData); |
|
138 void OpenIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID); |
|
139 void StartIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID); |
|
140 void ReleaseIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID); |
|
141 void SuspendIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID); |
|
142 void AbortIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID); |
|
143 void SecurityControlIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID, const HBufC8* aSecurityData); |
|
144 |
|
145 |
|
146 TInt SendSetConfigurationAccept(TAvdtpTransactionLabel aLabel); |
|
147 TInt SendSetConfigurationReject(TAvdtpTransactionLabel aLabel, TBluetoothAvDistributionError aResult, |
|
148 TAvdtpServiceCategory aCategory); |
|
149 |
|
150 TInt SendReconfigureAccept(TAvdtpTransactionLabel aLabel); |
|
151 TInt SendReconfigureReject(TAvdtpTransactionLabel aLabel, TBluetoothAvDistributionError aResult, |
|
152 TAvdtpServiceCategory aCategory); |
|
153 |
|
154 TInt SendStartAccept(TAvdtpTransactionLabel aLabel); |
|
155 TInt SendStartReject(TAvdtpTransactionLabel aLabel,TBluetoothAvDistributionError aResult, TSEID aBadSEID); |
|
156 TInt SendSuspendAccept(TAvdtpTransactionLabel aLabel); |
|
157 TInt SendSuspendReject(TAvdtpTransactionLabel aLabel,TBluetoothAvDistributionError aResult, TSEID aBadSEID); |
|
158 |
|
159 TInt SendSecurityControlAccept(TAvdtpTransactionLabel aLabel, const TDesC8* aOptionalData = NULL); |
|
160 TInt SendSecurityControlReject(TAvdtpTransactionLabel aLabel, TBluetoothAvDistributionError aResult); |
|
161 |
|
162 TInt SendReleaseAccept(TAvdtpTransactionLabel aLabel); |
|
163 |
|
164 // non-spec stuff |
|
165 TInt GetData(RMBufChain& aData, TUint aOptions, TSockAddr* anAddr=NULL); |
|
166 virtual void NewData(TUint aCount); |
|
167 |
|
168 // async stuff |
|
169 void StartTryToSendCallback(); |
|
170 void CancelTryToSendCallback(); |
|
171 static TInt TryToSendCallback(TAny *aSigCh); //the static one we have to register |
|
172 TInt TryToSendCallback(); //on this Signalling Channel |
|
173 private: |
|
174 // from MSocketNotify - transport (rather than packet) upcalls |
|
175 virtual void CanSend(); |
|
176 virtual void ConnectComplete(); |
|
177 virtual void ConnectComplete(const TDesC8& aConnectData); |
|
178 virtual void ConnectComplete(CServProviderBase& aSSP); |
|
179 virtual void ConnectComplete(CServProviderBase& aSSP,const TDesC8& aConnectData); |
|
180 virtual void CanClose(TDelete aDelete=EDelete); |
|
181 virtual void CanClose(const TDesC8& aDisconnectData,TDelete aDelete=EDelete); |
|
182 virtual void Disconnect(void); |
|
183 virtual void Disconnect(TDesC8& aDisconnectData); |
|
184 virtual void IoctlComplete(TDesC8 *aBuf); |
|
185 virtual void Error(TInt anError,TUint anOperationMask=EErrorAllOperations); |
|
186 virtual void NoBearer(const TDesC8& /*aConnectionInfo*/); |
|
187 virtual void Bearer(const TDesC8& aConnectionInfo); |
|
188 static TInt TryToClose(TAny* aSignallingChannel); |
|
189 |
|
190 private: |
|
191 // from MLogicalChannelFactoryClient |
|
192 void LogicalChannelFactoryRequestComplete(TLogicalChannelFactoryTicket aTicket, TInt aErr); |
|
193 private: |
|
194 CSignallingChannel(CAvdtpProtocol& aProtocol, CLogicalChannelFactory& aChannelFactory, const TBTDevAddr& aRemoteAddr); |
|
195 TInt EnqueueMessage(CSignallingTransaction& aTok); |
|
196 void ConstructL(); |
|
197 void RemoveTransactions(XAvdtpSignalReceiver& aUser); |
|
198 void PacketSent(CSignallingTransaction& aToken); |
|
199 void ObtainMTU(); |
|
200 void ConfigConfirm(TAvdtpTransactionLabel aLabel, |
|
201 TInt aResult, |
|
202 TAvdtpServiceCategory aCategory, |
|
203 TBool aReconfigure); |
|
204 |
|
205 CSignallingTransaction* PrepareSignallingCommand(XAvdtpSignalReceiver& aReceiver, TAvdtpMessage aMessage); |
|
206 CSignallingTransaction* PrepareSignallingResponse(TAvdtpMessageType aMessageType, TAvdtpMessage aMessage, TAvdtpTransactionLabel aLabel); |
|
207 CSignallingTransaction* PrepareSignallingPacket(TAvdtpMessageType aMessageType, TAvdtpMessage aMessage); |
|
208 |
|
209 |
|
210 CSignallingTransaction* FindTransaction(TAvdtpTransactionLabel aLabel); |
|
211 void HandleSignallingCommand(CAvdtpSignallingMessage& aSigMessage); |
|
212 |
|
213 void CheckOutboundQueue(); |
|
214 void ServiceOutboundQueue(); |
|
215 |
|
216 inline void SetBlocked(TBool aBlocked); |
|
217 inline TBool Blocked() const; |
|
218 |
|
219 ~CSignallingChannel(); //only this can delete this |
|
220 inline const TDblQue<XAvdtpSignalReceiver>& Users() const; |
|
221 |
|
222 // PDU operations not available for external use |
|
223 TInt SendAccept(TAvdtpTransactionLabel aLabel, TAvdtpMessage aMessage, const TDesC8* aOptionalData = NULL); |
|
224 |
|
225 TInt SendReject(TAvdtpTransactionLabel aLabel, |
|
226 TAvdtpMessage aMessage, |
|
227 TBluetoothAvDistributionError aError, |
|
228 const TDesC8* aRejectionData = NULL); |
|
229 void QueIdleTimer(); |
|
230 void ErrorPermanentUsers(TInt aError); |
|
231 void ErrorServiceRequesters(TInt aError); |
|
232 TBool CheckSignal(const CSignallingTransaction& aToken, TAvdtpMessage aSignal) const; |
|
233 void CancelIdleTimer(); |
|
234 TBool IsIdle() const; |
|
235 void IdledD(); |
|
236 |
|
237 private: |
|
238 CAvdtpProtocol& iProtocol; |
|
239 CLogicalChannelFactory& iLogicalChannelFactory; |
|
240 CServProviderBase* iBearer; |
|
241 TDblQueLink iProtocolQLink; |
|
242 TDblQue<XAvdtpSignalReceiver> iPermanentUsers; |
|
243 TDblQue<CSignallingTransaction> iTransactions; |
|
244 TInt iBearerMTU; |
|
245 |
|
246 /** |
|
247 this value is either the intended remote or the actual one |
|
248 whereas RemoteAddress() returns 0 if the connection is not actually in place |
|
249 */ |
|
250 TBTDevAddr iRemoteAddress; |
|
251 TTransactionLabelManager iLabelGen; |
|
252 |
|
253 /** |
|
254 There is always one and only one incoming message [can be empty] |
|
255 */ |
|
256 CAvdtpInboundSignallingMessage iInboundMessage; |
|
257 |
|
258 /** |
|
259 Messages being prepared by their Signalling Sessions. |
|
260 NB: this que will need to be purged of messages owned by a SS |
|
261 when it detaches (do we want to limit how many messages a SS can |
|
262 be preparing at once?) |
|
263 */ |
|
264 TDblQue<CAvdtpOutboundSignallingMessage> iDraftMessages; |
|
265 |
|
266 /** |
|
267 Messages sitting in our outbound queue |
|
268 */ |
|
269 TDblQue<CAvdtpOutboundSignallingMessage> iQueuedMessages; |
|
270 |
|
271 /** |
|
272 The fragments which have been prepared from a message plucked |
|
273 off the outbound que (and fragmented according to the MTU of |
|
274 the L2CAP channel). Only flushed if an ABORT appears in the |
|
275 queue for the _same_SEP_ [subtle, see AVDTP spec pp62]. |
|
276 */ |
|
277 RMBufChain iOutgoingSignallingMessage; |
|
278 TBool iMoreFrags; |
|
279 CSignallingTransaction* iCurrentTransaction; |
|
280 |
|
281 TBool iBlocked; |
|
282 |
|
283 CAsyncCallBack* iTryToSendCallback; // sig msgs sent asynchronously |
|
284 |
|
285 // these managers are "Connection-local" in spec, hence this class owns them |
|
286 TTCIDManager iTCIDManager; |
|
287 TTSIDManager iTSIDManager; |
|
288 |
|
289 TDeltaTimerEntry iIdleTimerEntry; //< Disconnection idle timer |
|
290 TBool iIdleTimerActive; //< Is Idle timer running. |
|
291 |
|
292 TLogicalChannelFactoryTicket iLogicalChannelRequest; // for passive request for now |
|
293 }; |
|
294 |
|
295 inline TTCIDManager& CSignallingChannel::TCIDManager() |
|
296 { |
|
297 return iTCIDManager; |
|
298 } |
|
299 |
|
300 inline TTSIDManager& CSignallingChannel::TSIDManager() |
|
301 { |
|
302 return iTSIDManager; |
|
303 } |
|
304 |
|
305 inline TBool CSignallingChannel::Blocked() const |
|
306 { |
|
307 return iBlocked; |
|
308 } |
|
309 |
|
310 inline void CSignallingChannel::SetBlocked(TBool aBlocked) |
|
311 { |
|
312 iBlocked=aBlocked; |
|
313 } |
|
314 |
|
315 inline const TDblQue<XAvdtpSignalReceiver>& CSignallingChannel::Users() const |
|
316 { |
|
317 return iPermanentUsers; |
|
318 } |
|
319 |
|
320 inline TBool CSignallingChannel::IsListening() const |
|
321 { |
|
322 return iRemoteAddress==TBTDevAddr(0); |
|
323 } |
|
324 |
|
325 #endif //AVDTPSIGNALLINGCHANNEL_H |
|
326 |