|
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 #include "csocketcontroller.h" |
|
17 |
|
18 #include "csocket.h" |
|
19 #include "csocketreader.h" |
|
20 #include "csocketwriter.h" |
|
21 #include "msocketcontrollerstore.h" |
|
22 #include "mconnectionprefsprovider.h" |
|
23 #include "httptransporthandlercommon.h" |
|
24 #include "thttptrlayerpanic.h" |
|
25 #include <escapeutils.h> |
|
26 |
|
27 CSocketController* CSocketController::NewL(CSocket* aSocket, MConnectionPrefsProvider& aConnectionPrefsProvider,TBool aPriority) |
|
28 /** |
|
29 The factory constructor. Ownership of the socket is transferred on calling |
|
30 the factory constructor. |
|
31 @param aSocket The connected socket. |
|
32 @return A pointer to a fully constructed object. |
|
33 */ |
|
34 { |
|
35 // Ownership of socket has been transferred - place on cleanup stack. |
|
36 CleanupStack::PushL(aSocket); |
|
37 |
|
38 // Transfer ownership of the socket to the socket controller. |
|
39 CSocketController* self = new (ELeave) CSocketController(aSocket, aConnectionPrefsProvider, aPriority); |
|
40 |
|
41 // Ownership of socket with the socket controller - pop-off the cleanup stack |
|
42 CleanupStack::Pop(aSocket); |
|
43 |
|
44 // Continue with initialisation of the socket controller |
|
45 CleanupStack::PushL(self); |
|
46 self->ConstructL( aConnectionPrefsProvider.GetRecvBufferSize() ); |
|
47 CleanupStack::Pop(self); |
|
48 return self; |
|
49 } |
|
50 |
|
51 CSocketController::~CSocketController() |
|
52 /** |
|
53 Destructor. |
|
54 */ |
|
55 { |
|
56 // Clean-up... |
|
57 delete iSocketReader; |
|
58 delete iSocketWriter; |
|
59 delete iSocket; |
|
60 delete iHost; |
|
61 } |
|
62 |
|
63 CSocketController::CSocketController(CSocket* aSocket, MConnectionPrefsProvider& aConnectionPrefsProvider, TBool aPriority) |
|
64 : CBase(), iSocket(aSocket), iPriority(aPriority), iConnectionPrefsProvider(aConnectionPrefsProvider) |
|
65 /** |
|
66 Constructor. |
|
67 @param aStore The socket controller store. |
|
68 @param aSocket The connected socket. |
|
69 */ |
|
70 { |
|
71 __ASSERT_DEBUG( iSocket, User::Invariant() ); |
|
72 } |
|
73 |
|
74 void CSocketController::ConstructL( TInt aRecvBufferSize ) |
|
75 /** |
|
76 Second phase constructor. Initialises the object. Ownership of the connected |
|
77 socket is passed to this class if this function completes. |
|
78 */ |
|
79 { |
|
80 // Create the socket reader and writer |
|
81 // Writer is created (and added to AS) first so that it has a 'higher priority' in AS. |
|
82 // Must keep this order since it guarantees that we receive the acknowledgement of data being |
|
83 // sent out before receiving the response, which is something we rely on. |
|
84 iSocketWriter = CSocketWriter::NewL(*iSocket, *this, iPriority); |
|
85 iSocketReader = CSocketReader::NewL(*iSocket, *this, aRecvBufferSize, iPriority); |
|
86 } |
|
87 |
|
88 void CSocketController::NotifyInStore(MSocketControllerStore& aStore) |
|
89 /** |
|
90 Notifier that this object is now owned by the socket controller store. |
|
91 @param aStore The socket controller store. |
|
92 */ |
|
93 { |
|
94 iStore = &aStore; |
|
95 } |
|
96 |
|
97 MInputStream& CSocketController::InputStream() const |
|
98 /** |
|
99 The access function for the input stream. |
|
100 @return The input stream object. |
|
101 */ |
|
102 { |
|
103 return *iSocketReader; |
|
104 } |
|
105 |
|
106 MOutputStream& CSocketController::OutputStream() const |
|
107 /** |
|
108 The access function for the output stream. |
|
109 @return The output stream object. |
|
110 */ |
|
111 { |
|
112 return *iSocketWriter; |
|
113 } |
|
114 |
|
115 /* |
|
116 * Methods from MSocketController |
|
117 */ |
|
118 |
|
119 void CSocketController::StreamClosed(TInt aError, MSocketController::TStreamType aStreamType) |
|
120 /** |
|
121 @see MSocketController |
|
122 */ |
|
123 { |
|
124 // Notify the other stream... |
|
125 switch( aStreamType ) |
|
126 { |
|
127 case EInputStream: |
|
128 { |
|
129 // The input stream has closed the socket - inform the socket writer |
|
130 iSocketWriter->SocketClosed(aError); |
|
131 } break; |
|
132 case EOutputStream: |
|
133 { |
|
134 // The output stream has closed the socket - inform the socket reader |
|
135 iSocketReader->SocketClosed(aError); |
|
136 } break; |
|
137 default: |
|
138 User::Invariant(); |
|
139 break; |
|
140 } |
|
141 |
|
142 // Both the input and output streams should be in the Closed state - this |
|
143 // socket controller is no longer useful. |
|
144 if( iStore ) |
|
145 { |
|
146 // Socket is closing, check if an immediate (abortive) socket close is required |
|
147 if(iConnectionPrefsProvider.ImmediateSocketShutdown()) |
|
148 { |
|
149 // This will have no effect on secure connections, secure connections will |
|
150 // be closed with default behaviour when iScoket is destroyed in the d'tor |
|
151 iSocket->ShutdownImmediate(); |
|
152 } |
|
153 |
|
154 // This socket controller is in the socket controller store - need to |
|
155 // remove it from there. |
|
156 iStore->SocketControllerShutdown(*this); |
|
157 |
|
158 // This object is now ownerless - it should be deleted. |
|
159 delete this; |
|
160 } |
|
161 // This socket controller is not owned by the socket controller store - the |
|
162 // owner (probably the cleanup stack) will delete it. |
|
163 } |
|
164 |
|
165 void CSocketController::StreamSuspend(MSocketController::TStreamType aStreamType) |
|
166 /** |
|
167 @see MSocketController |
|
168 */ |
|
169 { |
|
170 // Suspend the other stream... |
|
171 switch( aStreamType ) |
|
172 { |
|
173 case EInputStream: |
|
174 { |
|
175 // This is not supported yet! |
|
176 User::Invariant(); |
|
177 } break; |
|
178 case EOutputStream: |
|
179 { |
|
180 // The output stream has suspended the socket - inform the socket reader |
|
181 iSocketReader->Suspend(); |
|
182 } break; |
|
183 default: |
|
184 User::Invariant(); |
|
185 break; |
|
186 } |
|
187 } |
|
188 |
|
189 void CSocketController::StreamResume(MSocketController::TStreamType aStreamType) |
|
190 /** |
|
191 @see MSocketController |
|
192 */ |
|
193 { |
|
194 // Resume the other stream... |
|
195 switch( aStreamType ) |
|
196 { |
|
197 case EInputStream: |
|
198 { |
|
199 // This is not supported yet! |
|
200 User::Invariant(); |
|
201 } break; |
|
202 case EOutputStream: |
|
203 { |
|
204 // The output stream has resumed the socket - inform the socket reader |
|
205 iSocketReader->Resume(); |
|
206 } break; |
|
207 default: |
|
208 User::Invariant(); |
|
209 break; |
|
210 } |
|
211 } |
|
212 |
|
213 #ifdef _DEBUG |
|
214 void CSocketController::ConnectionInfo(TDes8& aRemoteHost, TUint16& aRemotePort, TUint16& aLocalPort) |
|
215 #else |
|
216 void CSocketController::ConnectionInfo(TDes8& /*aRemoteHost*/, TUint16& /*aRemotePort*/, TUint16& /*aLocalPort*/) |
|
217 #endif |
|
218 /** |
|
219 @see MSocketController |
|
220 */ { |
|
221 #ifdef _DEBUG |
|
222 __ASSERT_DEBUG( aRemoteHost.MaxLength() >= KIpv6MaxAddrSize, User::Invariant() ); |
|
223 |
|
224 TInetAddr addr; |
|
225 iSocket->RemoteName(addr); |
|
226 |
|
227 TBuf<KIpv6MaxAddrSize> ip16bit; |
|
228 addr.Output(ip16bit); |
|
229 |
|
230 aRemoteHost.Copy(ip16bit); |
|
231 aRemotePort = static_cast<TUint16>(addr.Port()); |
|
232 |
|
233 TInetAddr local; |
|
234 iSocket->LocalName(local); |
|
235 aLocalPort = static_cast<TUint16>(local.Port()); |
|
236 #else |
|
237 User::Invariant(); |
|
238 #endif |
|
239 } |
|
240 |
|
241 TBool CSocketController::HostAndPortMatches(const TDesC8& aHost, TUint16 aPort) |
|
242 { |
|
243 if(iHost == NULL) |
|
244 return EFalse; |
|
245 |
|
246 if(aHost.Compare(*iHost) == 0 && aPort == iPort) |
|
247 return ETrue; |
|
248 |
|
249 return EFalse; |
|
250 } |
|
251 |
|
252 void CSocketController::AssignRemoteHostInfoL(const TDesC& aHost, TUint16 aPort, const TInetAddr& aAddr) |
|
253 { |
|
254 iHost = EscapeUtils::ConvertFromUnicodeToUtf8L(aHost); |
|
255 iPort = aPort; |
|
256 iRemoteAddress = aAddr; |
|
257 } |
|
258 |
|
259 |