|
1 // Copyright (c) 1999-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 // Implement the L2CAP sap state classes. |
|
15 // These are CL2CAPSAPStateFactory, TL2CAPSAPState (abstract) and its derived |
|
16 // classes |
|
17 // Together, these classes and the SAP implement the State pattern |
|
18 // (GOF). The states themselves are implemented using the Flyweight |
|
19 // pattern. Each state is a Flyweight object, and CL2CAPSAPStateFactory |
|
20 // is manager of these objects. As a result of being a flyweight, no |
|
21 // state object may have state that can't be shared between all |
|
22 // possible users of the state (ie no per-SAP state) |
|
23 // |
|
24 // |
|
25 |
|
26 #include <bluetooth/logger.h> |
|
27 |
|
28 #include <bt_sock.h> |
|
29 |
|
30 #include "l2sapstates.h" |
|
31 |
|
32 #include "L2CapSDUQueue.h" |
|
33 #include "L2CapDataController.h" |
|
34 #include "l2capSAPSignalHandler.h" |
|
35 |
|
36 #include "l2sap.h" |
|
37 #include "l2cap.h" |
|
38 |
|
39 #include "l2util.h" |
|
40 |
|
41 #ifdef _DEBUG |
|
42 #include "L2CapDebugControlInterface.h" |
|
43 #endif |
|
44 |
|
45 #ifdef __FLOG_ACTIVE |
|
46 _LIT8(KLogComponent, LOG_COMPONENT_L2CAP); |
|
47 #endif |
|
48 |
|
49 /*************************************************************************/ |
|
50 // |
|
51 // TL2CAPSAPState Implementation |
|
52 // |
|
53 |
|
54 TL2CAPSAPState::TL2CAPSAPState(CL2CAPSAPStateFactory& aFactory) |
|
55 : iFactory(aFactory) |
|
56 { |
|
57 LOG_FUNC |
|
58 } |
|
59 |
|
60 void TL2CAPSAPState::PanicInState(TL2CAPPanic aPanic) const |
|
61 { |
|
62 LOG_FUNC |
|
63 Panic(aPanic, iFactory.StateIndex(this)); |
|
64 } |
|
65 |
|
66 #ifdef _DEBUG |
|
67 void TL2CAPSAPState::DebugPanicInState(TL2CAPPanic aPanic) const |
|
68 #else |
|
69 void TL2CAPSAPState::DebugPanicInState(TL2CAPPanic /*aPanic*/) const |
|
70 #endif |
|
71 { |
|
72 LOG_FUNC |
|
73 #ifdef _DEBUG |
|
74 PanicInState(aPanic); |
|
75 #endif |
|
76 } |
|
77 |
|
78 void TL2CAPSAPState::StartCalledWhileDisconnected(CL2CAPConnectionSAP& aSAP) const |
|
79 { |
|
80 LOG_FUNC |
|
81 // This function is intended to be called (under some circumstances when a Start() |
|
82 // has been received. This handles the case where in between the Start() call and |
|
83 // the construction of the cloned SAP on which the Start is being made, the link |
|
84 // which prompted the cloning has disconnected. Therefore, if we are a cloned sap |
|
85 // and have been "coupled" with an client side socket we need to inform it of the |
|
86 // disconnection. |
|
87 if(aSAP.ListeningSAP()) |
|
88 { |
|
89 if(aSAP.Socket()) |
|
90 { |
|
91 if(aSAP.SocketErrorCode() == KErrNone) |
|
92 { |
|
93 aSAP.Socket()->Disconnect(); |
|
94 } |
|
95 else |
|
96 { |
|
97 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
98 } |
|
99 } |
|
100 // We also need to take ourselves off the listening SAP's 'clone' queue, just |
|
101 // as we do in the fair weather case when Start is called in state 'Accepting'. |
|
102 aSAP.DetachFromListeningSAP(); |
|
103 } |
|
104 } |
|
105 |
|
106 // DEFAULT Implementations |
|
107 // Socket Initiated. |
|
108 void TL2CAPSAPState::Start(CL2CAPConnectionSAP& /*aSAP*/) const |
|
109 { |
|
110 LOG_FUNC |
|
111 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
112 } |
|
113 |
|
114 TInt TL2CAPSAPState::Ioctl(CL2CAPConnectionSAP& /*aSAP*/, TUint /*aLevel*/, TUint /*aName*/, TDes8* /*aOption*/) const |
|
115 { |
|
116 LOG_FUNC |
|
117 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
118 return KErrSAPUnexpectedEvent; |
|
119 } |
|
120 |
|
121 |
|
122 void TL2CAPSAPState::CancelIoctl(CL2CAPConnectionSAP& /*aSAP*/, TUint /*aLevel*/, TUint /*aName*/) const |
|
123 { |
|
124 LOG_FUNC |
|
125 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
126 } |
|
127 |
|
128 void TL2CAPSAPState::IoctlComplete(CL2CAPConnectionSAP& /*aSAP*/, TInt /*aErr*/, TUint /*aLevel*/, TUint /*aName*/, TDesC8* /*aBuf*/) const |
|
129 { |
|
130 LOG_FUNC |
|
131 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
132 } |
|
133 |
|
134 void TL2CAPSAPState::ActiveOpen(CL2CAPConnectionSAP& /*aSAP*/) const |
|
135 { |
|
136 LOG_FUNC |
|
137 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
138 } |
|
139 |
|
140 TInt TL2CAPSAPState::PassiveOpen(CL2CAPConnectionSAP& /*aSAP*/, TUint /*aQueSize*/) const |
|
141 { |
|
142 LOG_FUNC |
|
143 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
144 return KErrSAPUnexpectedEvent; |
|
145 } |
|
146 |
|
147 void TL2CAPSAPState::Shutdown(CL2CAPConnectionSAP& /* aSAP */) const |
|
148 { |
|
149 LOG_FUNC |
|
150 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
151 } |
|
152 |
|
153 void TL2CAPSAPState::FastShutdown(CL2CAPConnectionSAP& /* aSAP */) const |
|
154 { |
|
155 LOG_FUNC |
|
156 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
157 } |
|
158 |
|
159 TInt TL2CAPSAPState::Send(CL2CAPConnectionSAP& /*aSAP*/, RMBufChain& /*aData*/, TUint /*aFlag*/) const |
|
160 { |
|
161 LOG_FUNC |
|
162 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
163 return KErrNotReady; // Indicate that no data has been sent. |
|
164 } |
|
165 |
|
166 TInt TL2CAPSAPState::Read(CL2CAPConnectionSAP& /*aSAP*/, RMBufChain& /*aData*/) const |
|
167 { |
|
168 LOG_FUNC |
|
169 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
170 return KErrNotReady; |
|
171 } |
|
172 |
|
173 void TL2CAPSAPState::Bound(CL2CAPConnectionSAP& /*aSAP*/) const |
|
174 { |
|
175 LOG_FUNC |
|
176 PanicInState(EL2CAPUnexpectedSocketEvent); |
|
177 } |
|
178 |
|
179 // Events called from the SAP Signal Handler. |
|
180 void TL2CAPSAPState::ChannelConfigured(CL2CAPConnectionSAP& /*aSAP*/, |
|
181 CL2CapChannelConfig& /*aConfig*/, |
|
182 CL2CAPMux& /*aMuxer*/, |
|
183 TL2CAPPort /*aLocalPort*/, |
|
184 TL2CAPPort /*aRemotePort*/) |
|
185 { |
|
186 LOG_FUNC |
|
187 DebugPanicInState(EL2CAPUnexpectedSAPSignalHandlerEvent); |
|
188 } |
|
189 |
|
190 void TL2CAPSAPState::ReconfiguringChannel(CL2CAPConnectionSAP& /*aSAP*/) const |
|
191 { |
|
192 LOG_FUNC |
|
193 DebugPanicInState(EL2CAPUnexpectedSAPSignalHandlerEvent); |
|
194 } |
|
195 |
|
196 void TL2CAPSAPState::ChannelClosed(CL2CAPConnectionSAP& /*aSAP*/) const |
|
197 { |
|
198 LOG_FUNC |
|
199 PanicInState(EL2CAPUnexpectedSAPSignalHandlerEvent); |
|
200 } |
|
201 |
|
202 void TL2CAPSAPState::CloseOutgoingSDUQueue(CL2CAPConnectionSAP& /*aSAP*/) const |
|
203 { |
|
204 LOG_FUNC |
|
205 PanicInState(EL2CAPUnexpectedSAPSignalHandlerEvent); |
|
206 } |
|
207 |
|
208 void TL2CAPSAPState::SignalHandlerError(CL2CAPConnectionSAP& /*aSAP*/, TInt /*aErrorCode*/, MSocketNotify::TOperationBitmasks /*aErrorAction*/) const |
|
209 { |
|
210 LOG_FUNC |
|
211 PanicInState(EL2CAPUnexpectedSAPSignalHandlerEvent); |
|
212 } |
|
213 |
|
214 void TL2CAPSAPState::LinkUp(CL2CAPConnectionSAP& /*aSAP*/) const |
|
215 { |
|
216 LOG_FUNC |
|
217 PanicInState(EL2CAPUnexpectedSAPSignalHandlerEvent); |
|
218 } |
|
219 |
|
220 void TL2CAPSAPState::ChannelOpened(CL2CAPConnectionSAP& /*aSAP*/) const |
|
221 { |
|
222 LOG_FUNC |
|
223 PanicInState(EL2CAPUnexpectedSAPSignalHandlerEvent); |
|
224 } |
|
225 |
|
226 // Events called from the Data Controller. |
|
227 void TL2CAPSAPState::NewData(CL2CAPConnectionSAP& /*aSAP*/) const |
|
228 { |
|
229 LOG_FUNC |
|
230 PanicInState(EL2CAPUnexpectedDataControllerEvent); |
|
231 } |
|
232 |
|
233 TInt TL2CAPSAPState::NewDataAsyncCallBack(CL2CAPConnectionSAP& /*aSAP*/) const |
|
234 { |
|
235 LOG_FUNC |
|
236 PanicInState(EL2CAPUnexpectedDataControllerEvent); |
|
237 //Need to return something to stop error in compiler |
|
238 return(KErrNone); |
|
239 } |
|
240 |
|
241 void TL2CAPSAPState::CanSend(CL2CAPConnectionSAP& /*aSAP*/) const |
|
242 { |
|
243 LOG_FUNC |
|
244 PanicInState(EL2CAPUnexpectedDataControllerEvent); |
|
245 } |
|
246 |
|
247 void TL2CAPSAPState::SDUQueueClosed(CL2CAPConnectionSAP& /*aSAP*/) const |
|
248 { |
|
249 LOG_FUNC |
|
250 PanicInState(EL2CAPUnexpectedDataControllerEvent); |
|
251 } |
|
252 |
|
253 void TL2CAPSAPState::DataPlaneError(CL2CAPConnectionSAP& /*aSAP*/, TInt /*aErrorCode*/, MSocketNotify::TOperationBitmasks /*aErrorAction*/) const |
|
254 { |
|
255 LOG_FUNC |
|
256 PanicInState(EL2CAPUnexpectedDataControllerEvent); |
|
257 } |
|
258 |
|
259 // Events from the security manager. |
|
260 void TL2CAPSAPState::AccessRequestComplete(CL2CAPConnectionSAP& /*aSignalHandler*/, TInt /*aResult*/) const |
|
261 { |
|
262 LOG_FUNC |
|
263 PanicInState(EL2CAPUnexpectedSecurityManagerEvent); |
|
264 } |
|
265 |
|
266 |
|
267 // State Transition Actions. |
|
268 void TL2CAPSAPState::Enter(CL2CAPConnectionSAP& /*aSAP*/) const |
|
269 { |
|
270 LOG_FUNC |
|
271 } |
|
272 |
|
273 void TL2CAPSAPState::Exit(CL2CAPConnectionSAP& /*aSAP*/) const |
|
274 { |
|
275 LOG_FUNC |
|
276 } |
|
277 |
|
278 // Helper method. |
|
279 void TL2CAPSAPState::NotifySocketClosed(CL2CAPConnectionSAP& aSAP) const |
|
280 { |
|
281 LOG_FUNC |
|
282 // Enter the closed state. |
|
283 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EClosed)); |
|
284 |
|
285 // Check if this is owned by the socket yet. If it is the socket needs |
|
286 // to be notified, and is responsible for deleting this SAP. |
|
287 if(aSAP.Socket()) |
|
288 { |
|
289 switch(aSAP.ShutdownReceived()) |
|
290 { |
|
291 case CL2CAPConnectionSAP::ESAPShutdownNormal: |
|
292 aSAP.Socket()->CanClose(); |
|
293 break; |
|
294 |
|
295 case CL2CAPConnectionSAP::ESAPShutdownNone: |
|
296 if(aSAP.SocketErrorCode() == KErrNone) |
|
297 { |
|
298 aSAP.Socket()->Disconnect(); |
|
299 } |
|
300 else |
|
301 { |
|
302 // An error has occurred, enter the error state. |
|
303 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EError)); |
|
304 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
305 } |
|
306 break; |
|
307 |
|
308 case CL2CAPConnectionSAP::ESAPShutdownImmediate: |
|
309 break; |
|
310 |
|
311 default: |
|
312 PanicInState(EL2CAPInvalidSAPShutdownType); |
|
313 break; |
|
314 }; |
|
315 } |
|
316 else |
|
317 { |
|
318 if(!aSAP.IsAcceptPending()) |
|
319 { |
|
320 // This is not owned by a socket - delete it. |
|
321 aSAP.DetachFromListeningSAP(); |
|
322 aSAP.DeleteSAP(); |
|
323 } |
|
324 } |
|
325 } |
|
326 |
|
327 /*************************************************************************/ |
|
328 // |
|
329 // TL2CAPSAPStateClosed Implementation |
|
330 // |
|
331 TL2CAPSAPStateClosed::TL2CAPSAPStateClosed(CL2CAPSAPStateFactory& aFactory) |
|
332 : TL2CAPSAPState(aFactory) |
|
333 { |
|
334 LOG_FUNC |
|
335 } |
|
336 |
|
337 // Events called from the SAP. |
|
338 void TL2CAPSAPStateClosed::Start(CL2CAPConnectionSAP& aSAP) const |
|
339 { |
|
340 LOG_FUNC |
|
341 // If a passive connection was established and then disconnected by the peer |
|
342 // the Start notification will be received in this state. |
|
343 // This is handled in the Closed state rather than in the Bound state since |
|
344 // we're not bound from the stack's point of view in this situation. |
|
345 StartCalledWhileDisconnected(aSAP); |
|
346 } |
|
347 |
|
348 void TL2CAPSAPStateClosed::ActiveOpen(CL2CAPConnectionSAP& aSAP) const |
|
349 { |
|
350 LOG_FUNC |
|
351 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EActiveLinkPending)); |
|
352 |
|
353 // If there is a Service set for CodMan, register it. |
|
354 aSAP.RegisterCodService(); |
|
355 |
|
356 TInt rerr = aSAP.Protocol().MuxController().AttachActiveSignalHandler(aSAP.SignalHandler(), aSAP.RemoteDev()); |
|
357 if(rerr != KErrNone) |
|
358 { |
|
359 // Set up an error condition to indicate that the connection |
|
360 // has failed. |
|
361 aSAP.SetSocketErrorCode(KErrCouldNotConnect); |
|
362 aSAP.SetSocketErrorAction(MSocketNotify::EErrorConnect); |
|
363 |
|
364 NotifySocketClosed(aSAP); |
|
365 } |
|
366 } |
|
367 |
|
368 void TL2CAPSAPStateClosed::SDUQueueClosed(CL2CAPConnectionSAP& /*aSAP*/) const |
|
369 { |
|
370 LOG_FUNC |
|
371 // Nothing needs to be done here. FastShutdown scenario. |
|
372 } |
|
373 |
|
374 // Events called from the SAP Signal Handler. |
|
375 void TL2CAPSAPStateClosed::ChannelClosed(CL2CAPConnectionSAP& /*aSAP*/) const |
|
376 { |
|
377 LOG_FUNC |
|
378 // Ignore in this state. This will be due to a fast shutdown. |
|
379 } |
|
380 |
|
381 void TL2CAPSAPStateClosed::SignalHandlerError(CL2CAPConnectionSAP& /*aSAP*/, TInt /*aErrorCode*/, MSocketNotify::TOperationBitmasks /*aErrorAction*/) const |
|
382 { |
|
383 LOG_FUNC |
|
384 // Ignore in this state. This will be due to a fast shutdown. |
|
385 } |
|
386 |
|
387 void TL2CAPSAPStateClosed::Enter(CL2CAPConnectionSAP& aSAP) const |
|
388 { |
|
389 LOG_FUNC |
|
390 aSAP.iNewDataToNotify = 0; |
|
391 aSAP.DeregisterCodService(); // See if there is a Service to remove for CodMan |
|
392 } |
|
393 |
|
394 void TL2CAPSAPStateClosed::FastShutdown(CL2CAPConnectionSAP& /*aSAP*/) const |
|
395 { |
|
396 LOG_FUNC |
|
397 // Shutdown is permitted by ESOCK on an open (not connected) socket. |
|
398 // Therefore this must be handled in the closed or bound state. |
|
399 // No action required here. |
|
400 } |
|
401 |
|
402 void TL2CAPSAPStateClosed::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
403 { |
|
404 LOG_FUNC |
|
405 // Shutdown is permitted by ESOCK on an open (not connected) socket. |
|
406 // Therefore this must be handled in the closed or bound state. |
|
407 aSAP.Socket()->CanClose(); |
|
408 } |
|
409 |
|
410 void TL2CAPSAPStateClosed::Bound(CL2CAPConnectionSAP& aSAP) const |
|
411 { |
|
412 LOG_FUNC |
|
413 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EBound)); |
|
414 } |
|
415 |
|
416 TInt TL2CAPSAPStateClosed::NewDataAsyncCallBack(CL2CAPConnectionSAP& /*aSAP*/) const |
|
417 { |
|
418 LOG_FUNC |
|
419 //drop |
|
420 return EFalse; |
|
421 } |
|
422 |
|
423 /*************************************************************************/ |
|
424 // |
|
425 // TL2CAPSAPStateChannelPendingBase Implementation |
|
426 // |
|
427 TL2CAPSAPStateChannelPendingBase::TL2CAPSAPStateChannelPendingBase(CL2CAPSAPStateFactory& aFactory) |
|
428 : TL2CAPSAPState(aFactory) |
|
429 { |
|
430 LOG_FUNC |
|
431 } |
|
432 |
|
433 // Events called from the SAP Signal Handler. |
|
434 void TL2CAPSAPStateChannelPendingBase::SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
435 { |
|
436 LOG_FUNC |
|
437 // Store the error information. |
|
438 aSAP.SetSocketErrorCode(aErrorCode); |
|
439 aSAP.SetSocketErrorAction(aErrorAction); |
|
440 |
|
441 NotifySocketClosed(aSAP); |
|
442 } |
|
443 |
|
444 void TL2CAPSAPStateChannelPendingBase::ChannelClosed(CL2CAPConnectionSAP& aSAP) const |
|
445 { |
|
446 LOG_FUNC |
|
447 // Set up an error condition to indicate that the connection |
|
448 // has failed. |
|
449 aSAP.SetSocketErrorCode(KErrCouldNotConnect); |
|
450 aSAP.SetSocketErrorAction(MSocketNotify::EErrorConnect); |
|
451 |
|
452 NotifySocketClosed(aSAP); |
|
453 } |
|
454 |
|
455 // Events called from the SAP. |
|
456 void TL2CAPSAPStateChannelPendingBase::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
457 { |
|
458 LOG_FUNC |
|
459 // Enter the disconnecting state and disconnect the Mux. |
|
460 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
461 aSAP.SignalHandler().CloseChannelRequest(); |
|
462 } |
|
463 |
|
464 void TL2CAPSAPStateChannelPendingBase::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
465 { |
|
466 LOG_FUNC |
|
467 // Enter the closed state and disconnect the Mux. |
|
468 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EClosed)); |
|
469 aSAP.SignalHandler().CloseChannelRequest(); |
|
470 } |
|
471 |
|
472 /*************************************************************************/ |
|
473 // |
|
474 // TL2CAPSAPStatePassiveLinkPending Implementation |
|
475 // |
|
476 TL2CAPSAPStatePassiveLinkPending::TL2CAPSAPStatePassiveLinkPending(CL2CAPSAPStateFactory& aFactory) |
|
477 : TL2CAPSAPStateChannelPendingBase(aFactory) |
|
478 { |
|
479 LOG_FUNC |
|
480 } |
|
481 |
|
482 void TL2CAPSAPStatePassiveLinkPending::LinkUp(CL2CAPConnectionSAP& aSAP) const |
|
483 { |
|
484 LOG_FUNC |
|
485 // Forward the Connect Request event to the signalling state machine. |
|
486 aSAP.SignalHandler().ConnectRequestReceived(); |
|
487 |
|
488 // Start security checks. |
|
489 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EPassiveAccessRequestPending)); |
|
490 aSAP.StartAccessRequest(*(aSAP.ListeningSAP())); |
|
491 } |
|
492 |
|
493 /*************************************************************************/ |
|
494 // |
|
495 // TL2CAPSAPStateActiveLinkPending Implementation |
|
496 // |
|
497 TL2CAPSAPStateActiveLinkPending::TL2CAPSAPStateActiveLinkPending(CL2CAPSAPStateFactory& aFactory) |
|
498 : TL2CAPSAPStateChannelPendingBase(aFactory) |
|
499 { |
|
500 LOG_FUNC |
|
501 } |
|
502 |
|
503 void TL2CAPSAPStateActiveLinkPending::LinkUp(CL2CAPConnectionSAP& aSAP) const |
|
504 { |
|
505 LOG_FUNC |
|
506 // This is the first call to StartAccessRequest() for v2.1 clients. |
|
507 // For outgoing requests, we perform authentication both before the L2CAP |
|
508 // connection is started, and immediately after (for compatibility with |
|
509 // pre 2.1 clients). Here, we just set the required MITM settings; this |
|
510 // has no effect on pre-2.1 clients but this will succeed for 2.1 clients |
|
511 // and the subsequent call is effectively a null-operation. |
|
512 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EActiveSecMode4AccessRequestPending)); |
|
513 aSAP.StartAccessRequest(aSAP, ETrue); // indicate that this is outgiong security mode 4 |
|
514 } |
|
515 |
|
516 /*************************************************************************/ |
|
517 // |
|
518 // TL2CAPSAPStateActiveSecMode4AccessRequestPending Implementation |
|
519 // |
|
520 TL2CAPSAPStateActiveSecMode4AccessRequestPending::TL2CAPSAPStateActiveSecMode4AccessRequestPending(CL2CAPSAPStateFactory& aFactory) |
|
521 : TL2CAPSAPStateChannelPendingBase(aFactory) |
|
522 { |
|
523 LOG_FUNC |
|
524 } |
|
525 |
|
526 // Events called from the SAP. |
|
527 void TL2CAPSAPStateActiveSecMode4AccessRequestPending::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
528 { |
|
529 LOG_FUNC |
|
530 aSAP.CancelAccessRequest(); |
|
531 TL2CAPSAPStateChannelPendingBase::FastShutdown(aSAP); |
|
532 } |
|
533 |
|
534 void TL2CAPSAPStateActiveSecMode4AccessRequestPending::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
535 { |
|
536 LOG_FUNC |
|
537 aSAP.CancelAccessRequest(); |
|
538 TL2CAPSAPStateChannelPendingBase::Shutdown(aSAP); |
|
539 } |
|
540 |
|
541 // Events called from the SAP Signal Handler. |
|
542 void TL2CAPSAPStateActiveSecMode4AccessRequestPending::ChannelClosed(CL2CAPConnectionSAP& aSAP) const |
|
543 { |
|
544 LOG_FUNC |
|
545 aSAP.CancelAccessRequest(); |
|
546 TL2CAPSAPStateChannelPendingBase::ChannelClosed(aSAP); |
|
547 } |
|
548 |
|
549 void TL2CAPSAPStateActiveSecMode4AccessRequestPending::SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
550 { |
|
551 LOG_FUNC |
|
552 aSAP.CancelAccessRequest(); |
|
553 TL2CAPSAPStateChannelPendingBase::SignalHandlerError(aSAP, aErrorCode, aErrorAction); |
|
554 } |
|
555 |
|
556 void TL2CAPSAPStateActiveSecMode4AccessRequestPending::AccessRequestComplete(CL2CAPConnectionSAP& aSAP, TInt aResult) const |
|
557 { |
|
558 LOG_FUNC |
|
559 // Check the result from the security manager. |
|
560 switch(aResult) |
|
561 { |
|
562 case EBTSecManAccessGranted: |
|
563 // Inform the signalling state machine that the connect can be established. |
|
564 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EActiveChannelRequestPending)); |
|
565 aSAP.SignalHandler().OpenChannelRequest(); |
|
566 break; |
|
567 |
|
568 case EBTSecManAccessDenied: |
|
569 default: // Handle any error |
|
570 // Store the error information. |
|
571 aSAP.SetSocketErrorCode(KErrCouldNotConnect); |
|
572 aSAP.SetSocketErrorAction(MSocketNotify::EErrorConnect); |
|
573 |
|
574 // Call the helper method to move to the closed state and |
|
575 // let the peer know there is a security problem |
|
576 aSAP.SignalHandler().CloseChannelRequest(); |
|
577 break; |
|
578 }; |
|
579 } |
|
580 |
|
581 /*************************************************************************/ |
|
582 // |
|
583 // TL2CAPSAPStateActiveChannelRequestPending Implementation |
|
584 // |
|
585 TL2CAPSAPStateActiveChannelRequestPending::TL2CAPSAPStateActiveChannelRequestPending(CL2CAPSAPStateFactory& aFactory) |
|
586 : TL2CAPSAPStateChannelPendingBase(aFactory) |
|
587 { |
|
588 LOG_FUNC |
|
589 } |
|
590 |
|
591 void TL2CAPSAPStateActiveChannelRequestPending::ChannelOpened(CL2CAPConnectionSAP& aSAP) const |
|
592 { |
|
593 LOG_FUNC |
|
594 // A Channel is open but not configured. Perform security mode 2 security before |
|
595 // configuring the channel. |
|
596 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EActiveSecMode2AccessRequestPending)); |
|
597 |
|
598 // This is the second call to StartAccessRequest(), for pre-v2.1 clients. |
|
599 // For v2.1 clients, the authentication with MITM settings will have |
|
600 // already occurred, and so this call effectively does nothing. |
|
601 aSAP.StartAccessRequest(aSAP); |
|
602 } |
|
603 |
|
604 /*************************************************************************/ |
|
605 // |
|
606 // TL2CAPSAPStatePassiveAccessRequestPending Implementation |
|
607 // |
|
608 TL2CAPSAPStatePassiveAccessRequestPending::TL2CAPSAPStatePassiveAccessRequestPending(CL2CAPSAPStateFactory& aFactory) |
|
609 : TL2CAPSAPStateChannelPendingBase(aFactory) |
|
610 { |
|
611 LOG_FUNC |
|
612 } |
|
613 |
|
614 // Events called from the SAP. |
|
615 void TL2CAPSAPStatePassiveAccessRequestPending::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
616 { |
|
617 LOG_FUNC |
|
618 aSAP.CancelAccessRequest(); |
|
619 TL2CAPSAPStateChannelPendingBase::FastShutdown(aSAP); |
|
620 } |
|
621 |
|
622 void TL2CAPSAPStatePassiveAccessRequestPending::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
623 { |
|
624 LOG_FUNC |
|
625 aSAP.CancelAccessRequest(); |
|
626 TL2CAPSAPStateChannelPendingBase::Shutdown(aSAP); |
|
627 } |
|
628 |
|
629 // Events called from the SAP Signal Handler. |
|
630 void TL2CAPSAPStatePassiveAccessRequestPending::ChannelClosed(CL2CAPConnectionSAP& aSAP) const |
|
631 { |
|
632 LOG_FUNC |
|
633 aSAP.CancelAccessRequest(); |
|
634 TL2CAPSAPStateChannelPendingBase::ChannelClosed(aSAP); |
|
635 } |
|
636 |
|
637 void TL2CAPSAPStatePassiveAccessRequestPending::SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
638 { |
|
639 LOG_FUNC |
|
640 aSAP.CancelAccessRequest(); |
|
641 TL2CAPSAPStateChannelPendingBase::SignalHandlerError(aSAP, aErrorCode, aErrorAction); |
|
642 } |
|
643 |
|
644 // Events from the security manager. |
|
645 void TL2CAPSAPStatePassiveAccessRequestPending::AccessRequestComplete(CL2CAPConnectionSAP& aSAP, TInt aResult) const |
|
646 { |
|
647 LOG_FUNC |
|
648 // Check the result from the security manager. |
|
649 switch(aResult) |
|
650 { |
|
651 case EBTSecManAccessGranted: |
|
652 // Inform the signalling state machine that the connect can be established. |
|
653 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EPendingOpen)); |
|
654 aSAP.SignalHandler().OpenChannelRequest(); |
|
655 break; |
|
656 |
|
657 case EBTSecManAccessDenied: |
|
658 default: // Handle any error |
|
659 // Store the error information. |
|
660 aSAP.SetSocketErrorCode(KErrCouldNotConnect); |
|
661 aSAP.SetSocketErrorAction(MSocketNotify::EErrorConnect); |
|
662 |
|
663 // Call the helper method to move to the closed state and |
|
664 // let the peer know there is a security problem |
|
665 aSAP.SignalHandler().CloseChannelRequest(); |
|
666 break; |
|
667 }; |
|
668 } |
|
669 |
|
670 /*************************************************************************/ |
|
671 // |
|
672 // TL2CAPSAPStateActiveSecMode2AccessRequestPending Implementation |
|
673 // |
|
674 TL2CAPSAPStateActiveSecMode2AccessRequestPending::TL2CAPSAPStateActiveSecMode2AccessRequestPending(CL2CAPSAPStateFactory& aFactory) |
|
675 : TL2CAPSAPStateChannelPendingBase(aFactory) |
|
676 { |
|
677 LOG_FUNC |
|
678 } |
|
679 |
|
680 // Events called from the SAP. |
|
681 void TL2CAPSAPStateActiveSecMode2AccessRequestPending::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
682 { |
|
683 LOG_FUNC |
|
684 aSAP.CancelAccessRequest(); |
|
685 TL2CAPSAPStateChannelPendingBase::FastShutdown(aSAP); |
|
686 } |
|
687 |
|
688 void TL2CAPSAPStateActiveSecMode2AccessRequestPending::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
689 { |
|
690 LOG_FUNC |
|
691 aSAP.CancelAccessRequest(); |
|
692 TL2CAPSAPStateChannelPendingBase::Shutdown(aSAP); |
|
693 } |
|
694 |
|
695 // Events called from the SAP Signal Handler. |
|
696 void TL2CAPSAPStateActiveSecMode2AccessRequestPending::ChannelClosed(CL2CAPConnectionSAP& aSAP) const |
|
697 { |
|
698 LOG_FUNC |
|
699 aSAP.CancelAccessRequest(); |
|
700 TL2CAPSAPStateChannelPendingBase::ChannelClosed(aSAP); |
|
701 } |
|
702 |
|
703 void TL2CAPSAPStateActiveSecMode2AccessRequestPending::SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
704 { |
|
705 LOG_FUNC |
|
706 aSAP.CancelAccessRequest(); |
|
707 TL2CAPSAPStateChannelPendingBase::SignalHandlerError(aSAP, aErrorCode, aErrorAction); |
|
708 } |
|
709 |
|
710 // Events from the security manager. |
|
711 void TL2CAPSAPStateActiveSecMode2AccessRequestPending::AccessRequestComplete(CL2CAPConnectionSAP& aSAP, TInt aResult) const |
|
712 { |
|
713 LOG_FUNC |
|
714 // Check the result from the security manager. |
|
715 switch(aResult) |
|
716 { |
|
717 case EBTSecManAccessGranted: |
|
718 // Inform the signalling state machine that configuration can be started. |
|
719 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EPendingOpen)); |
|
720 aSAP.SignalHandler().ConfigureChannelRequest(); |
|
721 break; |
|
722 |
|
723 case EBTSecManAccessDenied: |
|
724 default: // Handle any error |
|
725 // Store the error information. |
|
726 aSAP.SetSocketErrorCode(KErrCouldNotConnect); |
|
727 aSAP.SetSocketErrorAction(MSocketNotify::EErrorConnect); |
|
728 |
|
729 // Enter the disconnecting state and disconnect the Mux. |
|
730 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
731 aSAP.SignalHandler().CloseChannelRequest(); |
|
732 break; |
|
733 }; |
|
734 } |
|
735 |
|
736 /*************************************************************************/ |
|
737 // |
|
738 // TL2CAPSAPStatePendingOpen Implementation |
|
739 // |
|
740 TL2CAPSAPStatePendingOpen::TL2CAPSAPStatePendingOpen(CL2CAPSAPStateFactory& aFactory) |
|
741 : TL2CAPSAPStateChannelPendingBase(aFactory) |
|
742 { |
|
743 LOG_FUNC |
|
744 } |
|
745 |
|
746 |
|
747 void TL2CAPSAPStatePendingOpen::ChannelConfigured(CL2CAPConnectionSAP& aSAP, |
|
748 CL2CapChannelConfig& aConfig, |
|
749 CL2CAPMux& aMuxer, |
|
750 TL2CAPPort aLocalPort, |
|
751 TL2CAPPort aRemotePort) |
|
752 { |
|
753 LOG_FUNC |
|
754 TInt rerr = aSAP.CreateDataPlane(aConfig, aMuxer, aLocalPort, aRemotePort); |
|
755 if(rerr == KErrNone) |
|
756 { |
|
757 // This changes the state. |
|
758 aSAP.SocketConnectComplete(); |
|
759 } |
|
760 else |
|
761 { |
|
762 // Failed to create the data plane. Close the connection and error the |
|
763 // socket. |
|
764 DataPlaneError(aSAP, rerr, MSocketNotify::TOperationBitmasks(MSocketNotify::EErrorSend | MSocketNotify::EErrorRecv)); |
|
765 } |
|
766 } |
|
767 |
|
768 // Events called from the Data Controller. |
|
769 void TL2CAPSAPStatePendingOpen::DataPlaneError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
770 { |
|
771 LOG_FUNC |
|
772 // Store the error condition, and disconnect the signalling. |
|
773 aSAP.SetSocketErrorCode(aErrorCode); |
|
774 aSAP.SetSocketErrorAction(aErrorAction); |
|
775 |
|
776 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
777 aSAP.SignalHandler().CloseChannelRequest(); |
|
778 } |
|
779 |
|
780 |
|
781 /*************************************************************************/ |
|
782 // |
|
783 // TL2CAPSAPStateListening Implementation |
|
784 // |
|
785 TL2CAPSAPStateListening::TL2CAPSAPStateListening(CL2CAPSAPStateFactory& aFactory) |
|
786 : TL2CAPSAPState(aFactory) |
|
787 { |
|
788 LOG_FUNC |
|
789 } |
|
790 |
|
791 // Events called from the SAP. |
|
792 void TL2CAPSAPStateListening::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
793 { |
|
794 LOG_FUNC |
|
795 // The listening sap is shutting down. |
|
796 aSAP.SignalHandler().CloseChannelRequest(); |
|
797 } |
|
798 |
|
799 void TL2CAPSAPStateListening::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
800 { |
|
801 LOG_FUNC |
|
802 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EClosed)); |
|
803 aSAP.SignalHandler().CloseChannelRequest(); |
|
804 } |
|
805 |
|
806 // State Transition Actions. |
|
807 void TL2CAPSAPStateListening::Enter(CL2CAPConnectionSAP& aSAP) const |
|
808 { |
|
809 LOG_FUNC |
|
810 aSAP.Protocol().MuxController().AttachListeningSignalHandler(aSAP.SignalHandler()); |
|
811 } |
|
812 |
|
813 void TL2CAPSAPStateListening::Exit(CL2CAPConnectionSAP& aSAP) const |
|
814 { |
|
815 LOG_FUNC |
|
816 aSAP.DeregisterCodService(); // See if there is a Service to remove for CodMan |
|
817 aSAP.Protocol().DecrementListeners(); |
|
818 aSAP.DeleteAllClones(); |
|
819 |
|
820 // Remove the signal handler from the list of listening SH. |
|
821 aSAP.SignalHandler().iLink.Deque(); |
|
822 |
|
823 // Check to see if the stack should be brought down |
|
824 aSAP.Protocol().TryToClose(); |
|
825 } |
|
826 |
|
827 // Events called from the SAP Signal Handler. |
|
828 void TL2CAPSAPStateListening::ChannelClosed(CL2CAPConnectionSAP& aSAP) const |
|
829 { |
|
830 LOG_FUNC |
|
831 // Call the helper method to move to the closed state and signal to the |
|
832 // socket that close is complete. |
|
833 NotifySocketClosed(aSAP); |
|
834 } |
|
835 |
|
836 |
|
837 /*************************************************************************/ |
|
838 // |
|
839 // TL2CAPSAPStateAccepting Implementation |
|
840 // |
|
841 TL2CAPSAPStateAccepting::TL2CAPSAPStateAccepting(CL2CAPSAPStateFactory& aFactory) |
|
842 : TL2CAPSAPStateOpen(aFactory) |
|
843 { |
|
844 LOG_FUNC |
|
845 } |
|
846 |
|
847 void TL2CAPSAPStateAccepting::ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const |
|
848 { |
|
849 LOG_FUNC |
|
850 aSAP.PauseDataPlane(); |
|
851 } |
|
852 |
|
853 // Events called from the Data Controller. |
|
854 void TL2CAPSAPStateAccepting::NewData(CL2CAPConnectionSAP& aSAP) const |
|
855 { |
|
856 LOG_FUNC |
|
857 aSAP.iNewDataToNotify++; |
|
858 } |
|
859 |
|
860 void TL2CAPSAPStateAccepting::Start(CL2CAPConnectionSAP& aSAP) const |
|
861 { |
|
862 LOG_FUNC |
|
863 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EOpen)); |
|
864 aSAP.DetachFromListeningSAP(); |
|
865 aSAP.StartNewDataAsyncCallBack(); |
|
866 } |
|
867 |
|
868 TInt TL2CAPSAPStateAccepting::NewDataAsyncCallBack(CL2CAPConnectionSAP& /*aSAP*/) const |
|
869 { |
|
870 LOG_FUNC |
|
871 PanicInState(EL2CAPUnexpectedDataControllerEvent); |
|
872 // Keep the compiler happy. |
|
873 return KErrNone; |
|
874 } |
|
875 |
|
876 void TL2CAPSAPStateAccepting::CanSend(CL2CAPConnectionSAP& /*aSAP*/) const |
|
877 { |
|
878 LOG_FUNC |
|
879 PanicInState(EL2CAPUnexpectedDataControllerEvent); |
|
880 } |
|
881 |
|
882 // State Transition Actions. |
|
883 void TL2CAPSAPStateAccepting::Exit(CL2CAPConnectionSAP& /*aSAP*/) const |
|
884 { |
|
885 LOG_FUNC |
|
886 } |
|
887 |
|
888 /*************************************************************************/ |
|
889 // |
|
890 // TL2CAPSAPStateAwaitingInitialData Implementation |
|
891 // |
|
892 TL2CAPSAPStateAwaitingInitialData::TL2CAPSAPStateAwaitingInitialData(CL2CAPSAPStateFactory& aFactory) |
|
893 : TL2CAPSAPStateOpen(aFactory) |
|
894 { |
|
895 LOG_FUNC |
|
896 } |
|
897 |
|
898 void TL2CAPSAPStateAwaitingInitialData::ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const |
|
899 { |
|
900 LOG_FUNC |
|
901 aSAP.PauseDataPlane(); |
|
902 } |
|
903 |
|
904 // Events called from the Data Controller. |
|
905 void TL2CAPSAPStateAwaitingInitialData::NewData(CL2CAPConnectionSAP& aSAP) const |
|
906 { |
|
907 LOG_FUNC |
|
908 aSAP.SignalHandler().ChannelConfigured(); |
|
909 |
|
910 aSAP.iNewDataToNotify++; |
|
911 aSAP.StartNewDataAsyncCallBack(); |
|
912 |
|
913 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EOpen)); |
|
914 } |
|
915 |
|
916 /*************************************************************************/ |
|
917 // |
|
918 // TL2CAPSAPStateOpen Implementation |
|
919 // |
|
920 TL2CAPSAPStateOpen::TL2CAPSAPStateOpen(CL2CAPSAPStateFactory& aFactory) |
|
921 : TL2CAPSAPState(aFactory) |
|
922 { |
|
923 LOG_FUNC |
|
924 } |
|
925 |
|
926 |
|
927 void TL2CAPSAPStateOpen::ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const |
|
928 { |
|
929 LOG_FUNC |
|
930 aSAP.PauseDataPlane(); |
|
931 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EAwaitingInitialData)); |
|
932 } |
|
933 |
|
934 void TL2CAPSAPStateOpen::ChannelConfigured(CL2CAPConnectionSAP& aSAP, |
|
935 CL2CapChannelConfig& aConfig, |
|
936 CL2CAPMux& /*aMuxer*/, |
|
937 TL2CAPPort /*aLocalPort*/, |
|
938 TL2CAPPort /*aRemotePort*/) |
|
939 { |
|
940 LOG_FUNC |
|
941 //This will be called after a successful reconfigure |
|
942 const TL2CapFecNegotiator& fec = aConfig.FecNegotiator(); |
|
943 TL2CapDataControllerConfig* dataConfig = new TL2CapDataControllerConfig(fec.DataControllerConfig()); |
|
944 |
|
945 if(dataConfig) |
|
946 { |
|
947 aSAP.DataQueue().ResumeSDUQueue(dataConfig, |
|
948 aConfig.OutgoingFlushTimeout().Negotiated().FlushTimeoutDuration(), |
|
949 fec.OutgoingMaximumPDUSize(), |
|
950 aConfig.OutgoingMTU().Negotiated().MTU(), |
|
951 aConfig.IncomingMTU().Negotiated().MTU()); |
|
952 |
|
953 // Adjust the optimal PDU size based on the new configuration values |
|
954 TPckgBuf<TInt> buf; |
|
955 TInt err = aSAP.GetOption(KSolBtACL, ELMOutboundACLSize, buf); |
|
956 |
|
957 TInt optimalPduSize = HL2CapPDU::GetPDUOrFragmentSize(aConfig.OutgoingMTU().Negotiated().MTU(), fec.OutgoingMaximumPDUSize(), (err == KErrNone) ? buf() : 0, aSAP.DataQueue().IsBasicDataVersion()); |
|
958 aSAP.DataQueue().SetOptimalPDUSize(optimalPduSize); |
|
959 |
|
960 // If this reconfiguration was initiated via an IOCTL complete it. |
|
961 aSAP.TryToCompleteConfigurationIoctl(KErrNone); |
|
962 } |
|
963 else |
|
964 { |
|
965 // If this reconfiguration was initiated via an IOCTL complete it. |
|
966 aSAP.TryToCompleteConfigurationIoctl(KErrNoMemory); |
|
967 DataPlaneError(aSAP, KErrNoMemory, MSocketNotify::TOperationBitmasks(MSocketNotify::EErrorSend | MSocketNotify::EErrorRecv)); |
|
968 } |
|
969 } |
|
970 |
|
971 // Events called from the SAP. |
|
972 TInt TL2CAPSAPStateOpen::Send(CL2CAPConnectionSAP& aSAP, RMBufChain& aData, TUint /*aFlag*/) const |
|
973 { |
|
974 LOG_FUNC |
|
975 TInt rerr = aSAP.DataQueue().Write(aData); |
|
976 if(rerr != KErrNone && rerr != KErrNotReady) |
|
977 { |
|
978 // Need to signal an error for the send operation. |
|
979 aSAP.Socket()->Error(rerr, MSocketNotify::EErrorSend); |
|
980 } |
|
981 return rerr; |
|
982 } |
|
983 |
|
984 TInt TL2CAPSAPStateOpen::Read(CL2CAPConnectionSAP& aSAP, RMBufChain& aData) const |
|
985 { |
|
986 LOG_FUNC |
|
987 // The return value is either an error or the number of datagrams read. |
|
988 TInt rValue = KErrNone; |
|
989 |
|
990 aSAP.DataQueue().Read(aData); |
|
991 if(aData.Length() > aSAP.DataQueue().MaxIncomingMTU()) |
|
992 { |
|
993 // This is larger then the negotiated MRU. Drop the SDU. |
|
994 aData.Free(); |
|
995 rValue = KErrOverflow; |
|
996 } |
|
997 else |
|
998 { |
|
999 rValue = (aData.Length() > 0); |
|
1000 } |
|
1001 return rValue; |
|
1002 } |
|
1003 |
|
1004 void TL2CAPSAPStateOpen::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
1005 { |
|
1006 LOG_FUNC |
|
1007 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
1008 |
|
1009 aSAP.DataQueue().CloseSDUQueue(CL2CapSDUQueue::EImmediatelyCloseIncomingQueue, |
|
1010 CL2CapSDUQueue::EDrainOutgoingQueue); |
|
1011 } |
|
1012 |
|
1013 void TL2CAPSAPStateOpen::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
1014 { |
|
1015 LOG_FUNC |
|
1016 // This needs to be shutdown within this stack frame. |
|
1017 // Move into the Closed state (Note. This transition de-activates |
|
1018 // park mode). Attempt to send a Disconnect Requests, and delete |
|
1019 // the data plane. |
|
1020 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EClosed)); |
|
1021 aSAP.SignalHandler().CloseChannelRequest(); |
|
1022 aSAP.SDUQueueClosed(); |
|
1023 } |
|
1024 |
|
1025 // Events called from the SAP Signal Handler. |
|
1026 void TL2CAPSAPStateOpen::CloseOutgoingSDUQueue(CL2CAPConnectionSAP& aSAP) const |
|
1027 { |
|
1028 LOG_FUNC |
|
1029 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
1030 |
|
1031 // Close the Outgoing SDU queue. |
|
1032 aSAP.DataQueue().CloseSDUQueue(CL2CapSDUQueue::EDrainIncomingQueue, |
|
1033 CL2CapSDUQueue::EImmediatelyCloseOutgoingQueue); |
|
1034 } |
|
1035 |
|
1036 void TL2CAPSAPStateOpen::ChannelClosed(CL2CAPConnectionSAP& aSAP) const |
|
1037 { |
|
1038 LOG_FUNC |
|
1039 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
1040 |
|
1041 // Close the Outgoing SDU queue. |
|
1042 aSAP.DataQueue().CloseSDUQueue(CL2CapSDUQueue::EDrainIncomingQueue, |
|
1043 CL2CapSDUQueue::EImmediatelyCloseOutgoingQueue); |
|
1044 } |
|
1045 |
|
1046 void TL2CAPSAPStateOpen::SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
1047 { |
|
1048 LOG_FUNC |
|
1049 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
1050 |
|
1051 CL2CapSDUQueue::TIncomingSDUQueueCloseAction icAct = (aErrorAction & MSocketNotify::EErrorRecv) ? |
|
1052 CL2CapSDUQueue::EImmediatelyCloseIncomingQueue : |
|
1053 CL2CapSDUQueue::EDrainIncomingQueue; |
|
1054 |
|
1055 CL2CapSDUQueue::TOutgoingSDUQueueCloseAction ogAct = (aErrorAction & MSocketNotify::EErrorSend) ? |
|
1056 CL2CapSDUQueue::EImmediatelyCloseOutgoingQueue : |
|
1057 CL2CapSDUQueue::EDrainOutgoingQueue; |
|
1058 |
|
1059 // Close the queue. Drain the queues according to the |
|
1060 // error action. |
|
1061 aSAP.DataQueue().CloseSDUQueue(icAct, ogAct); |
|
1062 |
|
1063 // Store the error information. |
|
1064 aSAP.SetSocketErrorCode(aErrorCode); |
|
1065 aSAP.SetSocketErrorAction(aErrorAction); |
|
1066 } |
|
1067 |
|
1068 |
|
1069 // Events called from the Data Controller. |
|
1070 void TL2CAPSAPStateOpen::NewData(CL2CAPConnectionSAP& aSAP) const |
|
1071 { |
|
1072 LOG_FUNC |
|
1073 aSAP.iNewDataToNotify++; |
|
1074 aSAP.StartNewDataAsyncCallBack(); |
|
1075 } |
|
1076 |
|
1077 TInt TL2CAPSAPStateOpen::NewDataAsyncCallBack(CL2CAPConnectionSAP& aSAP) const |
|
1078 { |
|
1079 LOG_FUNC |
|
1080 // Datagram i/f -- pass up no. of packets. |
|
1081 TUint16 newData = aSAP.iNewDataToNotify; |
|
1082 if(newData) |
|
1083 { |
|
1084 aSAP.iNewDataToNotify = 0; |
|
1085 aSAP.Socket()->NewData(newData); |
|
1086 } |
|
1087 return EFalse; |
|
1088 } |
|
1089 |
|
1090 void TL2CAPSAPStateOpen::CanSend(CL2CAPConnectionSAP& aSAP) const |
|
1091 { |
|
1092 LOG_FUNC |
|
1093 aSAP.Socket()->CanSend(); |
|
1094 } |
|
1095 |
|
1096 // Events called from the Data Controller. |
|
1097 void TL2CAPSAPStateOpen::DataPlaneError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
1098 { |
|
1099 LOG_FUNC |
|
1100 // Store the error condition, and disconnect the signalling. |
|
1101 aSAP.SetSocketErrorCode(aErrorCode); |
|
1102 aSAP.SetSocketErrorAction(aErrorAction); |
|
1103 |
|
1104 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EDisconnecting)); |
|
1105 |
|
1106 // Close the data plane. |
|
1107 aSAP.SDUQueueClosed(); |
|
1108 aSAP.SignalHandler().CloseChannelRequest(); |
|
1109 } |
|
1110 |
|
1111 |
|
1112 /*************************************************************************/ |
|
1113 // |
|
1114 // TL2CAPSAPStateDisconnecting Implementation |
|
1115 // |
|
1116 TL2CAPSAPStateDisconnecting::TL2CAPSAPStateDisconnecting(CL2CAPSAPStateFactory& aFactory) |
|
1117 : TL2CAPSAPState(aFactory) |
|
1118 { |
|
1119 LOG_FUNC |
|
1120 } |
|
1121 |
|
1122 void TL2CAPSAPStateDisconnecting::Start(CL2CAPConnectionSAP& aSAP) const |
|
1123 { |
|
1124 LOG_FUNC |
|
1125 // We do the same here as in the EClosed state, as under exceptional |
|
1126 // circumstances a slight race will result in the Start() coming in |
|
1127 // this state. |
|
1128 StartCalledWhileDisconnected(aSAP); |
|
1129 } |
|
1130 |
|
1131 // Events called from the SAP. |
|
1132 TInt TL2CAPSAPStateDisconnecting::Send(CL2CAPConnectionSAP& /*aSAP*/, RMBufChain& /*aData*/, TUint /*aFlag*/) const |
|
1133 { |
|
1134 LOG_FUNC |
|
1135 return KErrNotReady; // Indicate that no data has been sent. |
|
1136 } |
|
1137 |
|
1138 TInt TL2CAPSAPStateDisconnecting::Read(CL2CAPConnectionSAP& aSAP, RMBufChain& aData) const |
|
1139 { |
|
1140 LOG_FUNC |
|
1141 // The return value is either an error or the number of datagrams read. |
|
1142 TInt rValue = KErrNone; |
|
1143 |
|
1144 // Check if the queue is closed. |
|
1145 if(!aSAP.IsSDUQueueClosed()) |
|
1146 { |
|
1147 aSAP.DataQueue().Read(aData); |
|
1148 if(aData.Length() > aSAP.DataQueue().MaxIncomingMTU()) |
|
1149 { |
|
1150 // This is larger then the negotiated MRU. Drop the SDU. |
|
1151 aData.Free(); |
|
1152 rValue = KErrOverflow; |
|
1153 } |
|
1154 else |
|
1155 { |
|
1156 rValue = (aData.Length() > 0); |
|
1157 } |
|
1158 } |
|
1159 return rValue; |
|
1160 } |
|
1161 |
|
1162 void TL2CAPSAPStateDisconnecting::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
1163 { |
|
1164 LOG_FUNC |
|
1165 LOG(_L("L2CAP disconnecting state: shutdown")); |
|
1166 |
|
1167 // If the queue is still active, indicate that the incoming |
|
1168 // queue no longer needs to be drained. |
|
1169 if(!aSAP.IsSDUQueueClosed()) |
|
1170 { |
|
1171 LOG(_L(" -- need to close SDU queue")); |
|
1172 |
|
1173 aSAP.DataQueue().CloseSDUQueue(CL2CapSDUQueue::EImmediatelyCloseIncomingQueue, |
|
1174 CL2CapSDUQueue::EDrainOutgoingQueue); |
|
1175 } |
|
1176 } |
|
1177 |
|
1178 void TL2CAPSAPStateDisconnecting::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
1179 { |
|
1180 LOG_FUNC |
|
1181 LOG(_L("L2CAP disconnecting state: fast shutdown")); |
|
1182 |
|
1183 // This needs to be shutdown within this stack frame. |
|
1184 // Delete the data plane, attempt to send a Disconnect Requests |
|
1185 // and move into the Closed state. |
|
1186 aSAP.SignalHandler().CloseChannelRequest(); |
|
1187 |
|
1188 // This transition removes the park mode override. |
|
1189 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EClosed)); |
|
1190 aSAP.SDUQueueClosed(); |
|
1191 } |
|
1192 |
|
1193 // Events called from the SAP Signal Handler. |
|
1194 void TL2CAPSAPStateDisconnecting::ChannelClosed(CL2CAPConnectionSAP& aSAP) const |
|
1195 { |
|
1196 LOG_FUNC |
|
1197 // If the data plane is closed there is nothing more to be done. |
|
1198 if(aSAP.IsSDUQueueClosed()) |
|
1199 { |
|
1200 // Call the helper method to move to the closed state and signal to the |
|
1201 // socket that close is complete. |
|
1202 NotifySocketClosed(aSAP); |
|
1203 } |
|
1204 } |
|
1205 |
|
1206 void TL2CAPSAPStateDisconnecting::SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
1207 { |
|
1208 LOG_FUNC |
|
1209 // Store the error information. |
|
1210 aSAP.SetSocketErrorCode(aErrorCode); |
|
1211 aSAP.SetSocketErrorAction(aErrorAction); |
|
1212 |
|
1213 // The signalling has errored so a Disconnect Complete is no longer |
|
1214 // expected. |
|
1215 if(aSAP.IsSDUQueueClosed()) |
|
1216 { |
|
1217 // Call the helper method to move to the closed state and signal to the |
|
1218 // socket that close is complete. |
|
1219 NotifySocketClosed(aSAP); |
|
1220 } |
|
1221 else |
|
1222 { |
|
1223 // The SDU queue is still active. Ensure the correct queues are getting drained. |
|
1224 CL2CapSDUQueue::TIncomingSDUQueueCloseAction icAct = (aErrorAction & MSocketNotify::EErrorRecv) ? |
|
1225 CL2CapSDUQueue::EImmediatelyCloseIncomingQueue : |
|
1226 CL2CapSDUQueue::EDrainIncomingQueue; |
|
1227 |
|
1228 CL2CapSDUQueue::TOutgoingSDUQueueCloseAction ogAct = (aErrorAction & MSocketNotify::EErrorSend) ? |
|
1229 CL2CapSDUQueue::EImmediatelyCloseOutgoingQueue : |
|
1230 CL2CapSDUQueue::EDrainOutgoingQueue; |
|
1231 |
|
1232 // Close the queue. Drain the queues according to the |
|
1233 // error action. |
|
1234 aSAP.DataQueue().CloseSDUQueue(icAct, ogAct); |
|
1235 } |
|
1236 } |
|
1237 |
|
1238 void TL2CAPSAPStateDisconnecting::CloseOutgoingSDUQueue(CL2CAPConnectionSAP& aSAP) const |
|
1239 { |
|
1240 LOG_FUNC |
|
1241 // Close the Outgoing SDU queue. |
|
1242 aSAP.DataQueue().CloseSDUQueue(CL2CapSDUQueue::EImmediatelyCloseIncomingQueue, |
|
1243 CL2CapSDUQueue::EImmediatelyCloseOutgoingQueue); |
|
1244 } |
|
1245 |
|
1246 // Events called from the Data Controller. |
|
1247 void TL2CAPSAPStateDisconnecting::SDUQueueClosed(CL2CAPConnectionSAP& aSAP) const |
|
1248 { |
|
1249 LOG_FUNC |
|
1250 // The SDU queue has been disconnected. Check if Disconnect signalling |
|
1251 // is complete. |
|
1252 if(aSAP.SignalHandler().IsChannelClosed()) |
|
1253 { |
|
1254 // Call the helper method to move to the closed state and signal to the |
|
1255 // socket that close is complete. |
|
1256 NotifySocketClosed(aSAP); |
|
1257 } |
|
1258 else |
|
1259 { |
|
1260 // Signal disconnect to the signal handler. |
|
1261 aSAP.SignalHandler().CloseChannelRequest(); |
|
1262 } |
|
1263 } |
|
1264 |
|
1265 |
|
1266 void TL2CAPSAPStateDisconnecting::DataPlaneError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const |
|
1267 { |
|
1268 LOG_FUNC |
|
1269 // Store the error condition, and disconnect the signalling. |
|
1270 aSAP.SetSocketErrorCode(aErrorCode); |
|
1271 aSAP.SetSocketErrorAction(aErrorAction); |
|
1272 |
|
1273 // Close the data plane. |
|
1274 aSAP.SDUQueueClosed(); |
|
1275 } |
|
1276 |
|
1277 void TL2CAPSAPStateDisconnecting::NewData(CL2CAPConnectionSAP& /*aSAP*/) const |
|
1278 { |
|
1279 LOG_FUNC |
|
1280 // Data received in this state can be silently dropped. |
|
1281 } |
|
1282 |
|
1283 TInt TL2CAPSAPStateDisconnecting::NewDataAsyncCallBack(CL2CAPConnectionSAP& aSAP) const |
|
1284 { |
|
1285 LOG_FUNC |
|
1286 //Note we may have data received before moving into the |
|
1287 //disconnect state that we haven't yet informed ESock about |
|
1288 |
|
1289 //Datagram i/f -- pass up no. of packets |
|
1290 TUint16 newData = aSAP.iNewDataToNotify; |
|
1291 if(newData) |
|
1292 { |
|
1293 aSAP.iNewDataToNotify = 0; |
|
1294 aSAP.Socket()->NewData(newData); |
|
1295 } |
|
1296 return EFalse; |
|
1297 } |
|
1298 |
|
1299 void TL2CAPSAPStateDisconnecting::CanSend(CL2CAPConnectionSAP& aSAP) const |
|
1300 { |
|
1301 LOG_FUNC |
|
1302 // Check that the SDU queue is still open, and a Shutdown |
|
1303 // has not been received. |
|
1304 if(!aSAP.IsSDUQueueClosed() && aSAP.ShutdownReceived() == CL2CAPConnectionSAP::ESAPShutdownNone) |
|
1305 { |
|
1306 aSAP.Socket()->CanSend(); |
|
1307 } |
|
1308 } |
|
1309 |
|
1310 void TL2CAPSAPStateDisconnecting::ChannelConfigured(CL2CAPConnectionSAP& /*aSAP*/, |
|
1311 CL2CapChannelConfig& /*aConfig*/, |
|
1312 CL2CAPMux& /*aMuxer*/, |
|
1313 TL2CAPPort /*aLocalPort*/, |
|
1314 TL2CAPPort /*aRemotePort*/) |
|
1315 { |
|
1316 LOG_FUNC |
|
1317 // Drop this event as the SAP is closing. The SAP signal handler |
|
1318 // is still open to handle the exchange with the remote until |
|
1319 // the connection is closed. |
|
1320 } |
|
1321 |
|
1322 void TL2CAPSAPStateDisconnecting::ReconfiguringChannel(CL2CAPConnectionSAP& /*aSAP*/) const |
|
1323 { |
|
1324 LOG_FUNC |
|
1325 // Drop this event as the SAP is closing. The SAP signal handler |
|
1326 // is still open to handle the exchange with the remote until |
|
1327 // the connection is closed. |
|
1328 } |
|
1329 |
|
1330 /*************************************************************************/ |
|
1331 // |
|
1332 // TL2CAPSAPStateError Implementation |
|
1333 // |
|
1334 TL2CAPSAPStateError::TL2CAPSAPStateError(CL2CAPSAPStateFactory& aFactory) |
|
1335 : TL2CAPSAPState(aFactory) |
|
1336 { |
|
1337 LOG_FUNC |
|
1338 } |
|
1339 |
|
1340 // Events called from the SAP. |
|
1341 void TL2CAPSAPStateError::Start(CL2CAPConnectionSAP& aSAP) const |
|
1342 { |
|
1343 LOG_FUNC |
|
1344 // Error the socket to error/complete the outstanding request. |
|
1345 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1346 } |
|
1347 |
|
1348 TInt TL2CAPSAPStateError::Ioctl(CL2CAPConnectionSAP& aSAP, TUint /*aLevel*/, TUint /*aName*/, TDes8* /*aOption*/) const |
|
1349 { |
|
1350 LOG_FUNC |
|
1351 // Error the socket to error/complete the outstanding request. |
|
1352 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1353 return KErrNotReady; |
|
1354 } |
|
1355 |
|
1356 void TL2CAPSAPStateError::CancelIoctl(CL2CAPConnectionSAP& aSAP, TUint /*aLevel*/, TUint /*aName*/) const |
|
1357 { |
|
1358 LOG_FUNC |
|
1359 // Error the socket to error/complete the outstanding request. |
|
1360 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1361 } |
|
1362 |
|
1363 void TL2CAPSAPStateError::IoctlComplete(CL2CAPConnectionSAP& aSAP, TInt /*aErr*/, TUint /*aLevel*/, TUint /*aName*/, TDesC8* /*aBuf*/) const |
|
1364 { |
|
1365 LOG_FUNC |
|
1366 // Error the socket to error/complete the outstanding request. |
|
1367 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1368 } |
|
1369 |
|
1370 |
|
1371 void TL2CAPSAPStateError::ActiveOpen(CL2CAPConnectionSAP& aSAP) const |
|
1372 { |
|
1373 LOG_FUNC |
|
1374 // Error the socket to error/complete the outstanding request. |
|
1375 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1376 } |
|
1377 |
|
1378 TInt TL2CAPSAPStateError::PassiveOpen(CL2CAPConnectionSAP& aSAP, TUint /*aQueSize*/) const |
|
1379 { |
|
1380 LOG_FUNC |
|
1381 // Error the socket to error/complete the outstanding request. |
|
1382 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1383 return KErrNotReady; |
|
1384 } |
|
1385 |
|
1386 void TL2CAPSAPStateError::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
1387 { |
|
1388 LOG_FUNC |
|
1389 // The socket wishes to close the SAP, signal can close. |
|
1390 aSAP.Socket()->CanClose(); |
|
1391 } |
|
1392 |
|
1393 void TL2CAPSAPStateError::FastShutdown(CL2CAPConnectionSAP& /*aSAP*/) const |
|
1394 { |
|
1395 LOG_FUNC |
|
1396 // The SAP is about to be deleted by the socket. No action required in this state. |
|
1397 } |
|
1398 |
|
1399 |
|
1400 TInt TL2CAPSAPStateError::Send(CL2CAPConnectionSAP& aSAP, RMBufChain& /*aData*/, TUint /*aFlag*/) const |
|
1401 { |
|
1402 LOG_FUNC |
|
1403 // Error the socket to error/complete the outstanding request. |
|
1404 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1405 return KErrNotReady; // Indicate that no data has been sent. |
|
1406 } |
|
1407 |
|
1408 TInt TL2CAPSAPStateError::Read(CL2CAPConnectionSAP& aSAP, RMBufChain& /*aData*/) const |
|
1409 { |
|
1410 LOG_FUNC |
|
1411 // Error the socket to error/complete the outstanding request. |
|
1412 aSAP.Socket()->Error(aSAP.SocketErrorCode(), aSAP.SocketErrorAction()); |
|
1413 return KErrNotReady; |
|
1414 } |
|
1415 |
|
1416 // Events called from the SAP Signal Handler. |
|
1417 void TL2CAPSAPStateError::ChannelClosed(CL2CAPConnectionSAP& /*aSAP*/) const |
|
1418 { |
|
1419 LOG_FUNC |
|
1420 // Already in the error state so no need to transition. |
|
1421 // Consume the event. |
|
1422 } |
|
1423 |
|
1424 // State Transition Actions. |
|
1425 void TL2CAPSAPStateError::Enter(CL2CAPConnectionSAP& aSAP) const |
|
1426 { |
|
1427 LOG_FUNC |
|
1428 // Set the error action to error all requests from the socket. |
|
1429 aSAP.SetSocketErrorAction(MSocketNotify::EErrorAllOperations); |
|
1430 aSAP.DeregisterCodService(); // See if there is a Service to remove for CodMan |
|
1431 } |
|
1432 |
|
1433 /*************************************************************************/ |
|
1434 // |
|
1435 // TL2CAPSAPStateBound Implementation |
|
1436 // |
|
1437 TL2CAPSAPStateBound::TL2CAPSAPStateBound(CL2CAPSAPStateFactory& aFactory) |
|
1438 : TL2CAPSAPState(aFactory) |
|
1439 { |
|
1440 LOG_FUNC |
|
1441 } |
|
1442 |
|
1443 TInt TL2CAPSAPStateBound::PassiveOpen(CL2CAPConnectionSAP& aSAP, TUint aQueSize) const |
|
1444 { |
|
1445 LOG_FUNC |
|
1446 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EListening)); |
|
1447 |
|
1448 // would be nice to use Listening::Enter but return path of TInt is lost |
|
1449 TInt rerr = aSAP.Protocol().IncrementListeners(); |
|
1450 |
|
1451 aSAP.RegisterCodService(); // See if there is a Service set for CodMan |
|
1452 |
|
1453 if(rerr == KErrNone) |
|
1454 { |
|
1455 aSAP.iMaxAcceptingQCount = static_cast<TUint8>(aQueSize); |
|
1456 __ASSERT_DEBUG(aSAP.iClones.Count() == 0, PanicInState(EL2CAPUnexpectedSocketEvent)); |
|
1457 } |
|
1458 return rerr; |
|
1459 } |
|
1460 |
|
1461 // State Transition Actions. |
|
1462 void TL2CAPSAPStateBound::Enter(CL2CAPConnectionSAP& aSAP) const |
|
1463 { |
|
1464 LOG_FUNC |
|
1465 aSAP.Protocol().MuxController().AttachBoundSignalHandler(aSAP.SignalHandler()); |
|
1466 } |
|
1467 |
|
1468 void TL2CAPSAPStateBound::Exit(CL2CAPConnectionSAP& aSAP) const |
|
1469 { |
|
1470 LOG_FUNC |
|
1471 // Remove the signal handler from the list of bound SH. |
|
1472 aSAP.SignalHandler().iLink.Deque(); |
|
1473 |
|
1474 // Check to see if the stack needs to be brought down |
|
1475 aSAP.Protocol().TryToClose(); |
|
1476 } |
|
1477 |
|
1478 void TL2CAPSAPStateBound::FastShutdown(CL2CAPConnectionSAP& aSAP) const |
|
1479 { |
|
1480 LOG_FUNC |
|
1481 // Shutdown is permitted by ESOCK on an open (not connected) socket. |
|
1482 // Therefore this must be handled in the closed or bound state. |
|
1483 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EClosed)); |
|
1484 } |
|
1485 |
|
1486 void TL2CAPSAPStateBound::Shutdown(CL2CAPConnectionSAP& aSAP) const |
|
1487 { |
|
1488 LOG_FUNC |
|
1489 // Shutdown is permitted by ESOCK on an open (not connected) socket. |
|
1490 // Therefore this must be handled in the closed or bound state. |
|
1491 aSAP.SetState(iFactory.GetState(CL2CAPSAPStateFactory::EClosed)); |
|
1492 aSAP.Socket()->CanClose(); |
|
1493 } |
|
1494 |
|
1495 |
|
1496 /*************************************************************************/ |
|
1497 // |
|
1498 // CL2CAPSAPStateFactory Implementation |
|
1499 // |
|
1500 CL2CAPSAPStateFactory::CL2CAPSAPStateFactory() |
|
1501 { |
|
1502 LOG_FUNC |
|
1503 } |
|
1504 |
|
1505 CL2CAPSAPStateFactory::~CL2CAPSAPStateFactory() |
|
1506 { |
|
1507 LOG_FUNC |
|
1508 // Destroy all the state objects |
|
1509 iStates.DeleteAll(); |
|
1510 } |
|
1511 |
|
1512 CL2CAPSAPStateFactory* CL2CAPSAPStateFactory::NewL() |
|
1513 { |
|
1514 LOG_STATIC_FUNC |
|
1515 CL2CAPSAPStateFactory* factory= new (ELeave) CL2CAPSAPStateFactory(); |
|
1516 CleanupStack::PushL(factory); |
|
1517 |
|
1518 // Create all the new states |
|
1519 factory->iStates[EClosed] = new (ELeave) TL2CAPSAPStateClosed(*factory); |
|
1520 factory->iStates[EPassiveLinkPending] = new (ELeave) TL2CAPSAPStatePassiveLinkPending(*factory); |
|
1521 factory->iStates[EActiveLinkPending] = new (ELeave) TL2CAPSAPStateActiveLinkPending(*factory); |
|
1522 factory->iStates[EPassiveAccessRequestPending] = new (ELeave) TL2CAPSAPStatePassiveAccessRequestPending(*factory); |
|
1523 factory->iStates[EActiveSecMode2AccessRequestPending] = new (ELeave) TL2CAPSAPStateActiveSecMode2AccessRequestPending(*factory); |
|
1524 factory->iStates[EPendingOpen] = new (ELeave) TL2CAPSAPStatePendingOpen(*factory); |
|
1525 factory->iStates[EListening] = new (ELeave) TL2CAPSAPStateListening(*factory); |
|
1526 factory->iStates[EAccepting] = new (ELeave) TL2CAPSAPStateAccepting(*factory); |
|
1527 factory->iStates[EAwaitingInitialData] = new (ELeave) TL2CAPSAPStateAwaitingInitialData(*factory); |
|
1528 factory->iStates[EOpen] = new (ELeave) TL2CAPSAPStateOpen(*factory); |
|
1529 factory->iStates[EDisconnecting] = new (ELeave) TL2CAPSAPStateDisconnecting(*factory); |
|
1530 factory->iStates[EError] = new (ELeave) TL2CAPSAPStateError(*factory); |
|
1531 factory->iStates[EBound] = new (ELeave) TL2CAPSAPStateBound(*factory); |
|
1532 factory->iStates[EActiveSecMode4AccessRequestPending] = new (ELeave) TL2CAPSAPStateActiveSecMode4AccessRequestPending(*factory); |
|
1533 factory->iStates[EActiveChannelRequestPending] = new (ELeave) TL2CAPSAPStateActiveChannelRequestPending(*factory); |
|
1534 |
|
1535 CleanupStack::Pop(); |
|
1536 return factory; |
|
1537 } |
|
1538 |
|
1539 TL2CAPSAPState& CL2CAPSAPStateFactory::GetState(const TStates aState) const |
|
1540 { |
|
1541 LOG_FUNC |
|
1542 __ASSERT_DEBUG(aState != EMaxState, Panic(EL2CAPSAPMuxerStateOutOfBounds)); |
|
1543 return *iStates[aState]; |
|
1544 } |
|
1545 |
|
1546 TInt CL2CAPSAPStateFactory::StateIndex(const TL2CAPSAPState* aState) const |
|
1547 { |
|
1548 LOG_FUNC |
|
1549 TInt state; |
|
1550 for (state = 0; state < EMaxState; state++) |
|
1551 { |
|
1552 if (iStates[state] == aState) |
|
1553 { |
|
1554 return state; |
|
1555 } |
|
1556 } |
|
1557 |
|
1558 return KL2UnknownState; |
|
1559 } |
|
1560 |