|
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 // file descriptor transfer server - server implementation |
|
15 // |
|
16 // |
|
17 |
|
18 #include "fdtransfer_srv.h" |
|
19 #include "sysif.h" |
|
20 #include "fdesc.h" |
|
21 |
|
22 // ------------------------------------------------------------------------------- |
|
23 // CShutdown::ConstructL |
|
24 // ------------------------------------------------------------------------------- |
|
25 inline void CShutdown::ConstructL() |
|
26 { |
|
27 CTimer::ConstructL(); |
|
28 } |
|
29 |
|
30 // ------------------------------------------------------------------------------- |
|
31 // CShutdown::Start |
|
32 // Starts the timer for the specified time given |
|
33 // ------------------------------------------------------------------------------- |
|
34 inline void CShutdown::Start() |
|
35 { |
|
36 CActiveScheduler::Add(this); |
|
37 After(KFDTransferServerShutdownDelay); |
|
38 } |
|
39 |
|
40 // ------------------------------------------------------------------------------- |
|
41 // CShutdown::RunL |
|
42 // Initiate server exit when timer expires |
|
43 // ------------------------------------------------------------------------------- |
|
44 inline void CShutdown::RunL() |
|
45 { |
|
46 CActiveScheduler::Stop(); |
|
47 } |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 // ------------------------------------------------------------------------------- |
|
53 // CFileDesTransferSession::CreateL |
|
54 // 2nd phase construction for sessions. Invoked by the CServer2 framework |
|
55 // ------------------------------------------------------------------------------- |
|
56 inline void CFileDesTransferSession::CreateL() |
|
57 { |
|
58 Server().AddSession(); |
|
59 } |
|
60 |
|
61 |
|
62 // ------------------------------------------------------------------------------- |
|
63 // CFileDesTransferSession::ServiceL |
|
64 // Handle a client request. Leaves are handled by the ServiceError method. |
|
65 // ------------------------------------------------------------------------------- |
|
66 void CFileDesTransferSession::ServiceL(const RMessage2& aMsg) |
|
67 { |
|
68 switch (aMsg.Function()) |
|
69 { |
|
70 case ETransferFile: |
|
71 { |
|
72 GetfilesFromClient(aMsg); |
|
73 break; |
|
74 } |
|
75 case ETransferPipe: |
|
76 { |
|
77 GetPipesFromClient(aMsg); |
|
78 break; |
|
79 } |
|
80 default: |
|
81 { |
|
82 #ifdef _DEBUG |
|
83 RDebug::Printf("CFileDesTransferSession: Illegal message received"); |
|
84 #endif |
|
85 break; //_DEBUG |
|
86 } |
|
87 |
|
88 } |
|
89 } |
|
90 |
|
91 // ------------------------------------------------------------------------------- |
|
92 // CFileDesTransferSession::GetPipesFromClient |
|
93 // Inherits pipes from the client. |
|
94 // ------------------------------------------------------------------------------- |
|
95 void CFileDesTransferSession::GetPipesFromClient(const RMessage2& aMsg) const |
|
96 { |
|
97 CFileTable& ftable = const_cast<CFileTable&>(Backend()->FileTable()); |
|
98 TInt indx = aMsg.Int0(); |
|
99 RPipe pipe; |
|
100 TInt err = pipe.Open(aMsg, 1); |
|
101 |
|
102 if (err == KErrNone) |
|
103 { |
|
104 TUint16 mode = 0; |
|
105 if(aMsg.Int2()& O_NONBLOCK) |
|
106 mode |= O_NONBLOCK; |
|
107 |
|
108 if(indx > (ftable.iFids.Count()-1)) |
|
109 { |
|
110 TRAP(err,ftable.ExpandFTableL(indx+1)); |
|
111 } |
|
112 if(KErrNone == err) |
|
113 err = ftable.CreatePipeDesc(indx,pipe,mode); |
|
114 if (err != KErrNone) |
|
115 { |
|
116 pipe.Close(); |
|
117 } |
|
118 |
|
119 } |
|
120 aMsg.Complete(KErrNone); |
|
121 } |
|
122 |
|
123 // ------------------------------------------------------------------------------- |
|
124 // CFileDesTransferSession::GetfilesFromClient |
|
125 // Inherits normal files the client. |
|
126 // ------------------------------------------------------------------------------- |
|
127 void CFileDesTransferSession::GetfilesFromClient(const RMessage2& aMsg) const |
|
128 { |
|
129 |
|
130 CFileTable& ftable = const_cast<CFileTable&>((Backend()->FileTable())); |
|
131 TInt indx = aMsg.Int0(); |
|
132 CFileDesc* fdesc = (CFileDesc*)ftable.iPrivateHeap->AllocZ(sizeof(CFileDesc)); |
|
133 if (!fdesc) |
|
134 { |
|
135 aMsg.Complete(KErrNone); |
|
136 return; |
|
137 } |
|
138 fdesc = new (fdesc) CFileDesc; |
|
139 |
|
140 #if defined(SYMBIAN_OE_LARGE_FILE_SUPPORT) && !defined(SYMBIAN_OE_NO_LFS) |
|
141 //The integer width is bigger for 64 bit sizes |
|
142 TBuf<140> params; |
|
143 #else |
|
144 TBuf<60> params; |
|
145 #endif /* SYMBIAN_OE_LARGE_FILE_SUPPORT && !SYMBIAN_OE_NO_LFS */ |
|
146 |
|
147 aMsg.Read(1,params); |
|
148 TInt err = (fdesc->FileHandle()).AdoptFromClient(aMsg,2,3); |
|
149 if(indx > (ftable.iFids.Count()-1)) |
|
150 { |
|
151 TRAP(err,ftable.ExpandFTableL(indx+1)); |
|
152 } |
|
153 if (err == KErrNone) |
|
154 { |
|
155 fdesc->SetState(params); |
|
156 err = fdesc->CreateLock(); |
|
157 } |
|
158 if(err == KErrNone) |
|
159 { |
|
160 err = fdesc->Alloc(); |
|
161 } |
|
162 if(err == KErrNone) |
|
163 { |
|
164 ftable.Attach(indx, fdesc); |
|
165 |
|
166 } |
|
167 else |
|
168 { |
|
169 delete fdesc; |
|
170 (fdesc->FileHandle()).Close(); |
|
171 } |
|
172 aMsg.Complete(KErrNone); |
|
173 return ; |
|
174 } |
|
175 |
|
176 // ------------------------------------------------------------------------------- |
|
177 // CFileDesTransferSession::ServiceError |
|
178 // Handle an error from CFileTransferSession::ServiceL(). |
|
179 // ------------------------------------------------------------------------------- |
|
180 void CFileDesTransferSession::ServiceError(const RMessage2& aMsg, TInt aError) |
|
181 { |
|
182 CSession2::ServiceError(aMsg, aError); |
|
183 } |
|
184 |
|
185 // ------------------------------------------------------------------------------- |
|
186 // CFileDesTransferSession::Server |
|
187 // Obtain a reference to the server |
|
188 // ------------------------------------------------------------------------------- |
|
189 inline CFileDesTransferServer& CFileDesTransferSession::Server() |
|
190 { |
|
191 return *(static_cast<CFileDesTransferServer*>(const_cast<CServer2*>(CSession2::Server()))); |
|
192 } |
|
193 |
|
194 // ------------------------------------------------------------------------------- |
|
195 // CFileDesTransferSession::~CFileDesTransferSession |
|
196 // This session is destroyed. Gone forever. |
|
197 // ------------------------------------------------------------------------------- |
|
198 CFileDesTransferSession::~CFileDesTransferSession() |
|
199 { |
|
200 Server().DropSession(); |
|
201 } |
|
202 |
|
203 |
|
204 // ------------------------------------------------------------------------------- |
|
205 // CFileDesTransferServer::NewLC |
|
206 // Server constructor |
|
207 // ------------------------------------------------------------------------------- |
|
208 CFileDesTransferServer* CFileDesTransferServer::NewLC(RSemaphore& sem) |
|
209 { |
|
210 CFileDesTransferServer* pServer = new(ELeave) CFileDesTransferServer; |
|
211 CleanupStack::PushL(pServer); |
|
212 pServer->iSem = sem; |
|
213 pServer->ConstructL(); |
|
214 // Leave pServer on the cleanup stack |
|
215 return pServer; |
|
216 } |
|
217 |
|
218 |
|
219 // ------------------------------------------------------------------------------- |
|
220 // CFileDesTransferServer::ConstructL |
|
221 // Second phase construction. Create the shutdown timer object and the semaphore |
|
222 // ------------------------------------------------------------------------------- |
|
223 void CFileDesTransferServer::ConstructL() |
|
224 { |
|
225 iShutdown = new(ELeave) CShutdown; |
|
226 CleanupStack::PushL(iShutdown); |
|
227 iShutdown->ConstructL(); |
|
228 CleanupStack::Pop(); |
|
229 } |
|
230 |
|
231 // ------------------------------------------------------------------------------- |
|
232 // CFileDesTransferServer::AddToScheduler |
|
233 // Add both the server and the shutdown timer objects to the active scheduler |
|
234 // ------------------------------------------------------------------------------- |
|
235 TInt CFileDesTransferServer::AddToScheduler(const TDesC& aName) |
|
236 { |
|
237 iShutdown->Start(); |
|
238 return CServer2::Start(aName); |
|
239 } |
|
240 |
|
241 // ------------------------------------------------------------------------------- |
|
242 // CFileDesTransferServer::RemoveFromScheduler |
|
243 // Remove both the server and the shutdown timer objects from the active scheduler |
|
244 // ------------------------------------------------------------------------------- |
|
245 void CFileDesTransferServer::RemoveFromScheduler() |
|
246 { |
|
247 if (iShutdown->IsAdded()) |
|
248 { |
|
249 iShutdown->Deque(); |
|
250 } |
|
251 Deque(); |
|
252 } |
|
253 |
|
254 // ------------------------------------------------------------------------------- |
|
255 // CFileDesTransferServer::NewSessionL |
|
256 // Create a new client session. |
|
257 // ------------------------------------------------------------------------------- |
|
258 CSession2* CFileDesTransferServer::NewSessionL(const TVersion&, const RMessage2&) const |
|
259 { |
|
260 return new(ELeave) CFileDesTransferSession; |
|
261 } |
|
262 |
|
263 // ------------------------------------------------------------------------------- |
|
264 // CFileDesTransferServer::AddSession |
|
265 // A new session is created. Cancel the shutdown timer if it was running. |
|
266 // ------------------------------------------------------------------------------- |
|
267 inline void CFileDesTransferServer::AddSession() |
|
268 { |
|
269 iShutdown->Deque(); |
|
270 ++iSessionCount; |
|
271 |
|
272 } |
|
273 |
|
274 // ------------------------------------------------------------------------------- |
|
275 // CFileDesTransferServer::DropSession |
|
276 // The session is destroyed. Stop the ActiveScheduler |
|
277 // ------------------------------------------------------------------------------- |
|
278 inline void CFileDesTransferServer::DropSession() |
|
279 { |
|
280 if (--iSessionCount==0) |
|
281 { |
|
282 CActiveScheduler::Stop(); |
|
283 } |
|
284 } |
|
285 |
|
286 // ------------------------------------------------------------------------------- |
|
287 // CFileDesTransferServer::StartServer |
|
288 // Start serving. Blocks until the active scheduler is stopped from CShutdown::RunL |
|
289 // ------------------------------------------------------------------------------- |
|
290 |
|
291 void CFileDesTransferServer::StartServer() |
|
292 { |
|
293 iSem.Signal(); |
|
294 // Start the scheduler |
|
295 CActiveScheduler::Start(); |
|
296 // Block until |
|
297 } |
|
298 |
|
299 // ------------------------------------------------------------------------------- |
|
300 // CFileDesTransferServer::~CFileDesTransferServer |
|
301 // ------------------------------------------------------------------------------- |
|
302 CFileDesTransferServer::~CFileDesTransferServer() |
|
303 { |
|
304 iSem.Close(); |
|
305 delete iShutdown; |
|
306 } |