|
1 // Copyright (c) 2006-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 "imappaniccodes.h" |
|
24 #include "imaptransportmanagercommon.h" |
|
25 |
|
26 /** |
|
27 The factory constructor. Ownership of the socket is transferred on calling |
|
28 the factory constructor. |
|
29 |
|
30 @param aSocket The connected socket. |
|
31 @return A pointer to a fully constructed object. |
|
32 */ |
|
33 CSocketController* CSocketController::NewL(CSocket* aSocket, MConnectionPrefsProvider& aConnectionPrefsProvider) |
|
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); |
|
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(); |
|
47 CleanupStack::Pop(self); |
|
48 return self; |
|
49 } |
|
50 |
|
51 /** |
|
52 Destructor. |
|
53 */ |
|
54 CSocketController::~CSocketController() |
|
55 { |
|
56 // Clean-up... |
|
57 delete iSocketReader; |
|
58 delete iSocketWriter; |
|
59 delete iSocket; |
|
60 } |
|
61 |
|
62 /** |
|
63 Constructor. |
|
64 |
|
65 @param aStore The socket controller store. |
|
66 @param aSocket The connected socket. |
|
67 */ |
|
68 CSocketController::CSocketController(CSocket* aSocket, MConnectionPrefsProvider& aConnectionPrefsProvider) |
|
69 : CBase(), iSocket(aSocket), iConnectionPrefsProvider(aConnectionPrefsProvider) |
|
70 { |
|
71 __ASSERT_DEBUG( iSocket, User::Invariant() ); |
|
72 } |
|
73 |
|
74 /** |
|
75 Second phase constructor. Initialises the object. Ownership of the connected |
|
76 socket is passed to this class if this function completes. |
|
77 */ |
|
78 void CSocketController::ConstructL() |
|
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); |
|
85 iSocketReader = CSocketReader::NewL(*iSocket, *this); |
|
86 } |
|
87 |
|
88 /** |
|
89 Notifier that this object is now owned by the socket controller store. |
|
90 |
|
91 @param aStore The socket controller store. |
|
92 */ |
|
93 void CSocketController::NotifyInStore(MSocketControllerStore& aStore) |
|
94 { |
|
95 iStore = &aStore; |
|
96 } |
|
97 |
|
98 /** |
|
99 The access function for the input stream. |
|
100 |
|
101 @return The input stream object. |
|
102 */ |
|
103 MInputStream& CSocketController::InputStream() const |
|
104 { |
|
105 return *iSocketReader; |
|
106 } |
|
107 |
|
108 /** |
|
109 The access function for the output stream. |
|
110 |
|
111 @return The output stream object. |
|
112 */ |
|
113 MOutputStream& CSocketController::OutputStream() const |
|
114 { |
|
115 return *iSocketWriter; |
|
116 } |
|
117 |
|
118 /* |
|
119 * Methods from MSocketController |
|
120 */ |
|
121 |
|
122 /** |
|
123 @see MSocketController |
|
124 */ |
|
125 void CSocketController::StreamClosed(TInt aError, MSocketController::TStreamType aStreamType) |
|
126 { |
|
127 // Notify the other stream... |
|
128 switch( aStreamType ) |
|
129 { |
|
130 case EInputStream: |
|
131 { |
|
132 // The input stream has closed the socket - inform the socket writer |
|
133 iSocketWriter->SocketClosed(aError); |
|
134 } break; |
|
135 case EOutputStream: |
|
136 { |
|
137 // The output stream has closed the socket - inform the socket reader |
|
138 iSocketReader->SocketClosed(aError); |
|
139 } break; |
|
140 default: |
|
141 User::Invariant(); |
|
142 break; |
|
143 } |
|
144 |
|
145 // Both the input and output streams should be in the Closed state - this |
|
146 // socket controller is no longer useful. |
|
147 if( iStore ) |
|
148 { |
|
149 // This socket controller is in the socket controller store - need to |
|
150 // remove it from there. |
|
151 iStore->SocketControllerShutdown(*this); |
|
152 |
|
153 // This object is now ownerless - it should be deleted. |
|
154 delete this; |
|
155 } |
|
156 // This socket controller is not owned by the socket controller store - the |
|
157 // owner (probably the cleanup stack) will delete it. |
|
158 } |
|
159 |
|
160 /** |
|
161 @see MSocketController |
|
162 */ |
|
163 void CSocketController::StreamSuspended(MSocketController::TStreamType aSuspendedStream) |
|
164 { |
|
165 // Suspend the other stream... |
|
166 switch( aSuspendedStream ) |
|
167 { |
|
168 case EInputStream: |
|
169 { |
|
170 // This is not supported yet! |
|
171 User::Invariant(); |
|
172 } break; |
|
173 case EOutputStream: |
|
174 { |
|
175 // The output stream has suspended the socket - inform the socket reader |
|
176 iSocketReader->Suspend(); |
|
177 } break; |
|
178 default: |
|
179 User::Invariant(); |
|
180 break; |
|
181 } |
|
182 } |
|
183 |
|
184 /** |
|
185 @see MSocketController |
|
186 */ |
|
187 void CSocketController::StreamResumed(MSocketController::TStreamType aResumedStream) |
|
188 { |
|
189 // Resume the other stream... |
|
190 switch( aResumedStream ) |
|
191 { |
|
192 case EInputStream: |
|
193 { |
|
194 // This is not supported yet! |
|
195 User::Invariant(); |
|
196 } break; |
|
197 case EOutputStream: |
|
198 { |
|
199 // The output stream has resumed the socket - inform the socket reader |
|
200 iSocketReader->Resume(); |
|
201 } break; |
|
202 default: |
|
203 User::Invariant(); |
|
204 break; |
|
205 } |
|
206 } |
|
207 |
|
208 /** |
|
209 @see MSocketController |
|
210 */ |
|
211 #ifdef _DEBUG |
|
212 void CSocketController::ConnectionInfo(TDes8& aRemoteHost, TUint16& aRemotePort, TUint16& aLocalPort) |
|
213 #else |
|
214 void CSocketController::ConnectionInfo(TDes8& /*aRemoteHost*/, TUint16& /*aRemotePort*/, TUint16& /*aLocalPort*/) |
|
215 #endif |
|
216 { |
|
217 #ifdef _DEBUG |
|
218 __ASSERT_DEBUG( aRemoteHost.MaxLength() >= KIpv6MaxAddrSize, User::Invariant() ); |
|
219 |
|
220 TInetAddr addr; |
|
221 iSocket->RemoteName(addr); |
|
222 |
|
223 TBuf<KIpv6MaxAddrSize> ip16bit; |
|
224 addr.Output(ip16bit); |
|
225 |
|
226 aRemoteHost.Copy(ip16bit); |
|
227 aRemotePort = static_cast<TUint16>(addr.Port()); |
|
228 |
|
229 TInetAddr local; |
|
230 iSocket->LocalName(local); |
|
231 aLocalPort = static_cast<TUint16>(local.Port()); |
|
232 #else |
|
233 User::Invariant(); |
|
234 #endif |
|
235 } |