|
1 // Copyright (c) 2001-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 #include "ctcptransportlayer.h" |
|
17 #include "csocketlistener.h" |
|
18 #include "csocketconnector.h" |
|
19 #include "csocketcontroller.h" |
|
20 #include "thttptrlayerpanic.h" |
|
21 #include "mconnectionprefsprovider.h" |
|
22 |
|
23 #include "csocketreader.h" |
|
24 #include "csocketwriter.h" |
|
25 |
|
26 _LIT(KTcpProtName, "tcp"); |
|
27 |
|
28 CTcpTransportLayer* CTcpTransportLayer::NewL(TAny* aTransportConstructionParams) |
|
29 /** |
|
30 The factory constructor. |
|
31 @param aTransportConstructionParams A pointer to the instantiaton |
|
32 parameters |
|
33 @return A pointer to a fully constructed object. |
|
34 */ |
|
35 { |
|
36 THttpTransportConstructionParams* params = reinterpret_cast<THttpTransportConstructionParams*>(aTransportConstructionParams); |
|
37 CTcpTransportLayer* self = new (ELeave) CTcpTransportLayer(params->iConnectionPrefsProvider); |
|
38 CleanupStack::PushL(self); |
|
39 self->ConstructL(params); |
|
40 CleanupStack::Pop(self); |
|
41 return self; |
|
42 } |
|
43 |
|
44 CTcpTransportLayer::~CTcpTransportLayer() |
|
45 /** |
|
46 Destructor. |
|
47 */ |
|
48 { |
|
49 // Delete the socket listener |
|
50 delete iSocketListener; |
|
51 |
|
52 // Delete the socket connectors |
|
53 iConnectorStore.ResetAndDestroy(); |
|
54 |
|
55 // Delete the socket controllers |
|
56 iControllerStore.ResetAndDestroy(); |
|
57 |
|
58 // Close the socket server session if owned |
|
59 if( iOwnsConnection ) |
|
60 { |
|
61 if( iConnection ) |
|
62 { |
|
63 iConnection->Close(); |
|
64 delete iConnection; |
|
65 } |
|
66 } |
|
67 if( iOwnsSocketConnection ) |
|
68 { |
|
69 iSocketServer.Close(); |
|
70 } |
|
71 |
|
72 __FLOG_CLOSE; |
|
73 } |
|
74 |
|
75 CTcpTransportLayer::CTcpTransportLayer(MConnectionPrefsProvider& aTransLayerObserver) |
|
76 : CHttpTransportLayer(), iConnectionPrefsProvider(aTransLayerObserver) |
|
77 /** |
|
78 Constructor. |
|
79 */ |
|
80 { |
|
81 __FLOG_OPEN("http", "httptransporthandler.txt"); |
|
82 __FLOG(_T8("HTTP Transport Handler Log")); |
|
83 } |
|
84 |
|
85 void CTcpTransportLayer::ConstructL(THttpTransportConstructionParams* aTransportConstructionParams) |
|
86 /** |
|
87 Second phase constructor. Initialises the object. |
|
88 */ |
|
89 { |
|
90 // Callback on the observer for a Comms connection, otherwise create our own |
|
91 // Get socket server handle if set, otherwise start socket server. |
|
92 // Get RConnection handle if the connection is started else don't create our own |
|
93 // as we may or may not need one. eg; for localhost we don't need RConnection. |
|
94 iPriority = aTransportConstructionParams->iPriority; |
|
95 TInt socketServerHandle = 0; |
|
96 if( iConnectionPrefsProvider.SupplySocketServerHandle( socketServerHandle ) ) |
|
97 { |
|
98 iOwnsSocketConnection = EFalse; |
|
99 __ASSERT_ALWAYS( socketServerHandle!=0, THttpTrLayerPanic::Panic(THttpTrLayerPanic::EExpectedConnectionNotSupplied) ); |
|
100 |
|
101 iSocketServer.SetHandle(socketServerHandle); |
|
102 |
|
103 // Get RConnection handle if one available |
|
104 if ( iConnectionPrefsProvider.SupplyCommsConnection ( iConnection ) ) |
|
105 { |
|
106 __ASSERT_ALWAYS( iConnection!=NULL, THttpTrLayerPanic::Panic(THttpTrLayerPanic::EExpectedConnectionNotSupplied) ); |
|
107 iOwnsConnection = EFalse; |
|
108 } |
|
109 |
|
110 __FLOG_0(_T8("Transport Layer does not own SockServ session")); |
|
111 } |
|
112 else |
|
113 { |
|
114 iOwnsSocketConnection = ETrue; |
|
115 // Connect to the socket server and the handle |
|
116 |
|
117 User::LeaveIfError(iSocketServer.Connect()); |
|
118 iConnectionPrefsProvider.SetSocketServerHandleL ( iSocketServer.Handle() ); |
|
119 |
|
120 __FLOG_0(_T8("Transport Layer owns SockServ session")); |
|
121 } |
|
122 |
|
123 // Get the protocol description |
|
124 User::LeaveIfError(iSocketServer.FindProtocol(KTcpProtName(), iProtocolDescription)); |
|
125 } |
|
126 |
|
127 /* |
|
128 * Methods from CHttpTransportLayer |
|
129 */ |
|
130 |
|
131 void CTcpTransportLayer::CHttpTransportLayer_Reserved() |
|
132 /** |
|
133 @see CHttpTransportLayer |
|
134 */ |
|
135 { |
|
136 User::Invariant(); |
|
137 } |
|
138 |
|
139 /* |
|
140 * Methods from MSocketFactory |
|
141 */ |
|
142 |
|
143 void CTcpTransportLayer::ListenL(MSocketListenObserver& aObserver, TUint16 aPort) |
|
144 /** |
|
145 @see MSocketFactory |
|
146 */ |
|
147 { |
|
148 if( iSocketListener == NULL ) |
|
149 { |
|
150 // Create the socket listener object |
|
151 iSocketListener = CSocketListener::NewL(SocketControllerFactory(), CommsInfoProvider(), iPriority); |
|
152 |
|
153 |
|
154 #if defined (_DEBUG) && defined (_LOGGING) |
|
155 iSocketListener->__logger__ = this->__logger__; |
|
156 #endif |
|
157 } |
|
158 // Start the socket listener... |
|
159 iSocketListener->Listen(aObserver, aPort); |
|
160 } |
|
161 |
|
162 void CTcpTransportLayer::StopListen() |
|
163 /** |
|
164 @see MSocketFactory |
|
165 */ |
|
166 { |
|
167 __ASSERT_DEBUG( iSocketListener != NULL, User::Invariant() ); |
|
168 |
|
169 // Stop the socket listener... |
|
170 iSocketListener->StopListen(); |
|
171 } |
|
172 |
|
173 MSocketConnector& CTcpTransportLayer::ConnectL(MSocketConnectObserver& aObserver, const TDesC8& aRemoteHost, TUint16 aRemotePort) |
|
174 /** |
|
175 @see MSocketFactory |
|
176 */ |
|
177 { |
|
178 if(iOwnsSocketConnection) |
|
179 { |
|
180 TInt socketServerHandle = 0; |
|
181 if(iConnectionPrefsProvider.SupplySocketServerHandle(socketServerHandle)) |
|
182 { |
|
183 __FLOG_2(_T8("ConnectL: iSocketServer.Handle(): %d socketServerHandle: %d"), iSocketServer.Handle(), socketServerHandle); |
|
184 if ( iSocketServer.Handle() != socketServerHandle ) |
|
185 { |
|
186 __FLOG_0(_T8("Socket server handle is switching. Clear the connections / socket opened with the old socket server")); |
|
187 // Close all the sockets as we are swicthing to a different socket server |
|
188 for(TInt i = 0; i < iControllerStore.Count(); ++i) |
|
189 { |
|
190 iControllerStore[i]->InputStream().Shutdown(); |
|
191 // Socket and controller will be deleted by itself |
|
192 } |
|
193 iConnectorStore.ResetAndDestroy(); |
|
194 } |
|
195 } |
|
196 } |
|
197 |
|
198 // Create the socket connector |
|
199 CSocketConnector* socketConnector = CSocketConnector::NewL( |
|
200 SocketConnectorStore(), |
|
201 SocketControllerFactory(), |
|
202 CommsInfoProvider(),iPriority |
|
203 ); |
|
204 CleanupStack::PushL(socketConnector); |
|
205 |
|
206 #if defined (_DEBUG) && defined (_LOGGING) |
|
207 socketConnector->__logger__ = this->__logger__; |
|
208 #endif |
|
209 |
|
210 TInetAddr* addr = NULL; |
|
211 const TUint count = iControllerStore.Count(); |
|
212 for(TUint i = 0; i < count; ++i) |
|
213 { |
|
214 CSocketController* controller = iControllerStore[i]; |
|
215 if(controller->HostAndPortMatches(aRemoteHost, aRemotePort)) |
|
216 { |
|
217 addr = &controller->RemoteAddress(); |
|
218 } |
|
219 } |
|
220 |
|
221 // Start connection to remote host |
|
222 socketConnector->ConnectL(aObserver, aRemoteHost, aRemotePort, addr); |
|
223 |
|
224 // Add to the connector store |
|
225 User::LeaveIfError(iConnectorStore.Append(socketConnector)); |
|
226 |
|
227 // Ownership of the socket connector now transferred to the store. |
|
228 CleanupStack::Pop(socketConnector); |
|
229 |
|
230 return *socketConnector; |
|
231 } |
|
232 |
|
233 void CTcpTransportLayer::MSocketFactory_Reserved() |
|
234 /** |
|
235 @see MSocketFactory |
|
236 */ |
|
237 { |
|
238 User::Invariant(); |
|
239 } |
|
240 |
|
241 /* |
|
242 * Methods from MSocketControllerFactory |
|
243 */ |
|
244 |
|
245 CSocketController* CTcpTransportLayer::CreateSocketControllerLC(CSocket* aConnectedSocket) |
|
246 /** |
|
247 @see MSocketControllerFactory |
|
248 */ |
|
249 { |
|
250 __ASSERT_DEBUG( aConnectedSocket != NULL, User::Invariant() ); |
|
251 |
|
252 // A connection has been established on the given socket - create a socket |
|
253 // controller object to own the connected socket. |
|
254 CSocketController* socketController = CSocketController::NewL(aConnectedSocket, iConnectionPrefsProvider, iPriority); |
|
255 CleanupStack::PushL(socketController); |
|
256 |
|
257 #if defined (_DEBUG) && defined (_LOGGING) |
|
258 CSocketReader* reader = static_cast<CSocketReader*>(&socketController->InputStream()); |
|
259 CSocketWriter* writer = static_cast<CSocketWriter*>(&socketController->OutputStream()); |
|
260 |
|
261 reader->__logger__ = this->__logger__; |
|
262 writer->__logger__ = this->__logger__; |
|
263 #endif |
|
264 |
|
265 return socketController; |
|
266 } |
|
267 |
|
268 CSocketController* CTcpTransportLayer::CreateSocketControllerLC(CSocket* aConnectedSocket, const TDesC& aRemoteHost, TUint16 aRemotePort, const TInetAddr& aRemoteAddr) |
|
269 { |
|
270 __ASSERT_DEBUG( aConnectedSocket != NULL, User::Invariant() ); |
|
271 // A connection has been established on the given socket - create a socket |
|
272 // controller object to own the connected socket. |
|
273 CSocketController* socketController = CSocketController::NewL(aConnectedSocket, iConnectionPrefsProvider, iPriority); |
|
274 CleanupStack::PushL(socketController); |
|
275 socketController->AssignRemoteHostInfoL(aRemoteHost, aRemotePort, aRemoteAddr); |
|
276 #if defined (_DEBUG) && defined (_LOGGING) |
|
277 CSocketReader* reader = static_cast<CSocketReader*>(&socketController->InputStream()); |
|
278 CSocketWriter* writer = static_cast<CSocketWriter*>(&socketController->OutputStream()); |
|
279 |
|
280 reader->__logger__ = this->__logger__; |
|
281 writer->__logger__ = this->__logger__; |
|
282 #endif |
|
283 |
|
284 return socketController; |
|
285 |
|
286 } |
|
287 |
|
288 void CTcpTransportLayer::AddToStoreL(CSocketController* aSocketController) |
|
289 /** |
|
290 @see MSocketControllerFactory |
|
291 */ |
|
292 { |
|
293 __ASSERT_DEBUG( aSocketController, User::Invariant() ); |
|
294 |
|
295 // Ownership has been transferred - place on cleanup stack. |
|
296 CleanupStack::PushL(aSocketController); |
|
297 |
|
298 // Append to the store |
|
299 TInt err = iControllerStore.Append(aSocketController); |
|
300 if(err!=KErrNone) |
|
301 { |
|
302 aSocketController->InputStream().Reset(); |
|
303 aSocketController->OutputStream().Reset(); |
|
304 User::Leave(err); |
|
305 } |
|
306 |
|
307 // The store now owns the socket controller |
|
308 CleanupStack::Pop(aSocketController); |
|
309 |
|
310 // Notify the socket controller that it's in the store |
|
311 aSocketController->NotifyInStore(SocketControllerStore()); |
|
312 } |
|
313 |
|
314 /* |
|
315 * Methods from MSocketConnectorStore |
|
316 */ |
|
317 |
|
318 void CTcpTransportLayer::ConnectionCompleted(CSocketConnector& aOrphanedSocketConnector) |
|
319 /** |
|
320 @see MSocketConnectorStore |
|
321 */ |
|
322 { |
|
323 // Find the appropriate index for this connector |
|
324 TInt index = iConnectorStore.Count(); |
|
325 TBool found = EFalse; |
|
326 while( !found && index > 0 ) |
|
327 { |
|
328 found = &aOrphanedSocketConnector == iConnectorStore[--index]; |
|
329 } |
|
330 __ASSERT_DEBUG( found, User::Invariant() ); |
|
331 |
|
332 // Remove the socket connector from the store and compress the store. |
|
333 iConnectorStore.Remove(index); |
|
334 iConnectorStore.Compress(); |
|
335 } |
|
336 |
|
337 /* |
|
338 * Methods from MSocketControllerStore |
|
339 */ |
|
340 |
|
341 void CTcpTransportLayer::SocketControllerShutdown(CSocketController& aOrphanedSocketController) |
|
342 /** |
|
343 @see MSocketControllerStore |
|
344 */ |
|
345 { |
|
346 // Find the appropriate index for this connector |
|
347 TInt index = iControllerStore.Count(); |
|
348 TBool found = EFalse; |
|
349 while( !found && index > 0 ) |
|
350 { |
|
351 found = &aOrphanedSocketController == iControllerStore[--index]; |
|
352 } |
|
353 __ASSERT_DEBUG( found, User::Invariant() ); |
|
354 |
|
355 // Remove the socket controller from the store and compress the store. |
|
356 iControllerStore.Remove(index); |
|
357 iControllerStore.Compress(); |
|
358 } |
|
359 |
|
360 /* |
|
361 * Methods from MCommsInfoProvider |
|
362 */ |
|
363 |
|
364 RSocketServ& CTcpTransportLayer::SocketServer() |
|
365 /** |
|
366 @see MCommsInfoProvider |
|
367 */ |
|
368 { |
|
369 // Callback on the observer for a Comms connection, otherwise create our own |
|
370 // Get socket server handle if set, otherwise start socket server. |
|
371 // Get RConnection handle if the connection is started else don't create our own |
|
372 // as we may or may not need one. eg; for localhost we don't need RConnection. |
|
373 if ( iOwnsSocketConnection ) |
|
374 { |
|
375 TInt socketServerHandle = 0; |
|
376 if( iConnectionPrefsProvider.SupplySocketServerHandle( socketServerHandle ) ) |
|
377 { |
|
378 if ( iSocketServer.Handle() != socketServerHandle ) |
|
379 { |
|
380 iOwnsSocketConnection = EFalse; |
|
381 iSocketServer.Close(); |
|
382 __ASSERT_ALWAYS( socketServerHandle!=0, THttpTrLayerPanic::Panic(THttpTrLayerPanic::EExpectedConnectionNotSupplied) ); |
|
383 iSocketServer.SetHandle(socketServerHandle); |
|
384 |
|
385 __FLOG_0(_T8("Transport Layer does not own SockServ session")); |
|
386 // Get the protocol description |
|
387 iSocketServer.FindProtocol(KTcpProtName(), iProtocolDescription); |
|
388 } |
|
389 } |
|
390 } |
|
391 return iSocketServer; |
|
392 } |
|
393 |
|
394 TProtocolDesc& CTcpTransportLayer::ProtocolDescription() |
|
395 /** |
|
396 @see MCommsInfoProvider |
|
397 */ |
|
398 { |
|
399 return iProtocolDescription; |
|
400 } |
|
401 |
|
402 RConnection& CTcpTransportLayer::Connection() |
|
403 /** |
|
404 @see MCommsInfoProvider |
|
405 */ |
|
406 { |
|
407 return *iConnection; |
|
408 } |
|
409 |
|
410 void CTcpTransportLayer::SecurityPreferences(TBool& aDialogPrompt, MSecurityPolicy*& aSecurityPolicy) |
|
411 /** |
|
412 @see MCommsInfoProvider |
|
413 */ |
|
414 { |
|
415 iConnectionPrefsProvider.GetSecurityPrefs(aDialogPrompt, aSecurityPolicy); |
|
416 } |
|
417 |
|
418 TBool CTcpTransportLayer::OwnsConnection() |
|
419 /** |
|
420 @see MCommsInfoProvider |
|
421 */ |
|
422 { |
|
423 return iOwnsConnection; |
|
424 } |
|
425 |
|
426 |
|
427 TInt CTcpTransportLayer::SessionId() |
|
428 /** |
|
429 @see MCommsInfoProvider |
|
430 */ |
|
431 { |
|
432 return iConnectionPrefsProvider.SessionId(); |
|
433 } |
|
434 |
|
435 void CTcpTransportLayer::StartDefaultCommsConnectionL () |
|
436 { |
|
437 // See client has one RConnection started |
|
438 if ( iConnectionPrefsProvider.SupplyCommsConnection ( iConnection ) ) |
|
439 { |
|
440 __ASSERT_ALWAYS( iConnection!=NULL, THttpTrLayerPanic::Panic(THttpTrLayerPanic::EExpectedConnectionNotSupplied) ); |
|
441 iOwnsConnection = EFalse; |
|
442 return; |
|
443 } |
|
444 // Otherwise create and start one |
|
445 iConnection = new(ELeave) RConnection(); |
|
446 iOwnsConnection = ETrue; |
|
447 User::LeaveIfError(iConnection->Open(iSocketServer)); |
|
448 User::LeaveIfError(iConnection->Start()); //using default CommDb Settings |
|
449 iConnectionPrefsProvider.SetCommsConnectionL( iConnection ); |
|
450 __FLOG_0(_T8("Transport Layer owns default comms connection")); |
|
451 } |
|
452 |
|
453 TBool CTcpTransportLayer::HasConnection() |
|
454 { |
|
455 if ( iOwnsConnection || iConnection == NULL ) |
|
456 { |
|
457 RConnection* aRConnFromHttpSess; |
|
458 // Get RConnection handle if one available |
|
459 if ( iConnectionPrefsProvider.SupplyCommsConnection ( aRConnFromHttpSess ) ) |
|
460 { |
|
461 if ( aRConnFromHttpSess != iConnection ) |
|
462 { |
|
463 __ASSERT_ALWAYS( aRConnFromHttpSess!=NULL, THttpTrLayerPanic::Panic(THttpTrLayerPanic::EExpectedConnectionNotSupplied) ); |
|
464 iOwnsConnection = EFalse; |
|
465 if( iConnection ) |
|
466 { |
|
467 iConnection->Close(); |
|
468 delete iConnection; |
|
469 } |
|
470 iConnection = aRConnFromHttpSess; |
|
471 } |
|
472 } |
|
473 } |
|
474 return ( iConnection != NULL ); |
|
475 } |
|
476 |
|
477 |