|
1 /* |
|
2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 #include <e32math.h> |
|
29 |
|
30 //#include "SenHostletConnectionLog.h" |
|
31 #include "senservicemanagerdefines.h" // internal Core\inc - IPC enumerations |
|
32 |
|
33 #include "rsenhostletconnection.h" |
|
34 #include "senchunk.h" |
|
35 |
|
36 #include "sendebug.h" |
|
37 #include "senlogger.h" |
|
38 |
|
39 #include <SenSoapMessage.h> |
|
40 |
|
41 #if defined (__WINS__) && !defined(EKA2) |
|
42 static const TUint KServerMinHeapSize = 0x1000; // 4K |
|
43 static const TUint KServerMaxHeapSize = 0x100000; // 1000K |
|
44 #endif |
|
45 |
|
46 static TInt StartServerL(); |
|
47 static TInt CreateServerProcessL(); |
|
48 |
|
49 RSenHostletConnection::RSenHostletConnection() |
|
50 : RSessionBase(), iTlsLogChannel(1000) |
|
51 { |
|
52 // No implementation required |
|
53 } |
|
54 |
|
55 TInt RSenHostletConnection::Connect() |
|
56 { |
|
57 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::Connect"); |
|
58 TInt error(KErrNone); |
|
59 TRAPD(err, error = ::StartServerL()); |
|
60 |
|
61 if(err != KErrNone) |
|
62 { |
|
63 error = err; |
|
64 } |
|
65 if(KErrNone == error) |
|
66 { |
|
67 TLSLOG(iTlsLogChannel, KMinLogLevel, |
|
68 _L("RSenHostletConnection::Connect - Now creating session")); |
|
69 error = CreateSession(KSenServiceManager, |
|
70 Version(), |
|
71 KDefaultMessageSlots); |
|
72 #ifdef _SENDEBUG |
|
73 if(error != KErrNone) |
|
74 { |
|
75 TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, |
|
76 _L("RSenHostletConnection::Connect - CreateSession returned error: (%d)"), error)); |
|
77 } |
|
78 else |
|
79 { |
|
80 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::Connect - CreateSession returned KErrNone"); |
|
81 } |
|
82 #endif // _SENDEBUG |
|
83 } |
|
84 #ifdef _SENDEBUG |
|
85 else |
|
86 { |
|
87 TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, |
|
88 _L8("RSenHostletConnection::Connect - StartServerL failed, error: (%d)"), error)); |
|
89 } |
|
90 #endif // _SENDEBUG |
|
91 return error; |
|
92 } |
|
93 |
|
94 TVersion RSenHostletConnection::Version() const |
|
95 { |
|
96 TLSLOG(iTlsLogChannel, KMinLogLevel, _L("RSenHostletConnection::Version")); |
|
97 return(TVersion(KWsfServMajorVersionNumber, |
|
98 KWsfServMinorVersionNumber, |
|
99 KWsfServBuildVersionNumber)); |
|
100 } |
|
101 |
|
102 void RSenHostletConnection::CancelSession(TRequestStatus& aStatus) |
|
103 { |
|
104 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenServiceConnection::CancelSession(sync)"); |
|
105 SendReceive(ESenServCancelSession, aStatus); |
|
106 } |
|
107 |
|
108 |
|
109 // SYNC: Called from CSenHostletConnection::ConstructL |
|
110 TInt RSenHostletConnection::Establish(TDesC8& aHostletServiceDescription) |
|
111 { |
|
112 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::EstablishL"); |
|
113 |
|
114 TLSLOG_ALL(iTlsLogChannel, KMaxLogLevel, aHostletServiceDescription); |
|
115 |
|
116 TInt sdLength = aHostletServiceDescription.Length(); |
|
117 |
|
118 TIpcArgs args; |
|
119 args.Set(0, &aHostletServiceDescription); |
|
120 args.Set(1, sdLength); |
|
121 |
|
122 return SendReceive(ESenServEstablishHostletConnection, args); |
|
123 } |
|
124 |
|
125 // ASYNC: Completes when request handle is ready to be acquired |
|
126 void RSenHostletConnection::AwaitRequest(TRequestStatus& aStatus, |
|
127 TDes8& aErrPtr, |
|
128 TDes8& aTxnPtr) |
|
129 { |
|
130 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::AwaitRequest"); |
|
131 |
|
132 TIpcArgs args; |
|
133 args.Set(0, &aErrPtr); |
|
134 args.Set(1, &aTxnPtr); |
|
135 SendReceive(ESenServAwaitHostletRequest, args, aStatus); |
|
136 } |
|
137 |
|
138 // SYNC: returns RHandleBase ID if successful |
|
139 TInt RSenHostletConnection::AcquireRequestHandle( TDes8& aErrPtr, TDes8& aTxnPtr ) |
|
140 { |
|
141 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::AcquireRequestHandle"); |
|
142 |
|
143 TIpcArgs args; |
|
144 args.Set(0, &aErrPtr); |
|
145 args.Set(1, &aTxnPtr); |
|
146 return SendReceive(ESenServTransaction, args); |
|
147 } |
|
148 |
|
149 void RSenHostletConnection::ProvideResponse( TRequestStatus& aStatus, |
|
150 TDes8& aErrPtr, |
|
151 TDes8& aTxnPtr, |
|
152 CSenChunk& aClientOp, |
|
153 const TInt aResponseCode ) |
|
154 { |
|
155 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::ProvideResponse"); |
|
156 |
|
157 TIpcArgs args; |
|
158 args.Set(0, &aErrPtr); |
|
159 args.Set(1, &aTxnPtr); |
|
160 aClientOp.ChunkToArgs(args,2); |
|
161 args.Set(3, aResponseCode); |
|
162 SendReceive(ESenServProvideHostletResponse, args, aStatus); |
|
163 } |
|
164 |
|
165 TInt RSenHostletConnection::ConnectionID() |
|
166 { |
|
167 TInt connectionID = SendReceive( ESenServConnectionID ); |
|
168 |
|
169 iTlsLogChannel = KSenHostletConnectionLogChannelBase + connectionID; |
|
170 //TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L("- Connection ID: (%d)"), connectionID)); |
|
171 return connectionID; |
|
172 } |
|
173 |
|
174 TInt RSenHostletConnection::RegisterTransferObserver( |
|
175 const TDesC* aServerName, TAny* aConnection) |
|
176 { |
|
177 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::RegisterTransferObserver"); |
|
178 CActiveSchedulerWait asWait; |
|
179 TIpcArgs args(aServerName, aConnection, &asWait); |
|
180 TRequestStatus rs = KRequestPending; |
|
181 SendReceive(ESenObserveTransfer, args, rs); |
|
182 Mem::FillZ(&asWait, sizeof(asWait)); |
|
183 asWait.Start(); |
|
184 User::WaitForRequest(rs); |
|
185 TLSLOG_L(iTlsLogChannel, KMinLogLevel, "RSenHostletConnection::RegisterTransferObserver Completed"); |
|
186 return rs.Int(); |
|
187 } |
|
188 |
|
189 //void RSenHostletConnection::SetTlsLogChannel(TInt aTlsLogChannel) |
|
190 // { |
|
191 // iTlsLogChannel = aTlsLogChannel; |
|
192 // } |
|
193 |
|
194 static TInt StartServerL() |
|
195 { |
|
196 TInt result(KErrNotFound); |
|
197 |
|
198 #ifdef _SENDEBUG |
|
199 RFileLogger log; |
|
200 CleanupClosePushL(log); |
|
201 User::LeaveIfError( log.Connect() ); |
|
202 log.CreateLog(KSenHostletConnectionLogDir, _L("SenStartServer.log"), EFileLoggingModeAppend); |
|
203 log.Write(_L("StartServerL() invoked by HC.")); |
|
204 #endif |
|
205 |
|
206 TFindServer findSenServiceManager(KSenServiceManager); |
|
207 TFullName name; |
|
208 |
|
209 result = findSenServiceManager.Next(name); |
|
210 if (result == KErrNone) |
|
211 { |
|
212 // Server already running |
|
213 #ifdef _SENDEBUG |
|
214 log.Write(_L8("- Server already running, KErrNone")); |
|
215 log.CloseLog(); |
|
216 CleanupStack::PopAndDestroy(); // log.Close() |
|
217 #endif // _SENDEBUG |
|
218 return KErrNone; |
|
219 } |
|
220 |
|
221 RSemaphore semaphore; |
|
222 CleanupClosePushL(semaphore); |
|
223 |
|
224 // First, try to open the semaphore (if someone else created it already): |
|
225 result = semaphore.OpenGlobal( KSenServiceManagerSemaphoreName ); |
|
226 if( result == KErrNone ) |
|
227 { |
|
228 // If another client is starting up SEN.EXE, this client should return |
|
229 // to re-connect loop (wait one sec, max 5 times) |
|
230 #ifdef _SENDEBUG |
|
231 log.Write(_L8("- OpenGlobal OK => Another client already starting up SEN.EXE. About to WAIT and RE-CONNECT.")); |
|
232 #endif |
|
233 result = KErrServerBusy; |
|
234 } |
|
235 else // could not find any already opened global semaphore ==> it is safe to create new one |
|
236 { |
|
237 // Semaphore has not yet been created, so instantiate it now(!) |
|
238 result = semaphore.CreateGlobal( KSenServiceManagerSemaphoreName, 0 ); |
|
239 #ifdef _SENDEBUG |
|
240 if( result != KErrNone ) |
|
241 { |
|
242 log.Write(_L8("CreateGlobal failed")); |
|
243 log.WriteFormat(_L8("- error: %d"), result); |
|
244 } |
|
245 #endif |
|
246 } |
|
247 |
|
248 if (result != KErrNone) |
|
249 { |
|
250 CleanupStack::PopAndDestroy(); // semaphore.Close() |
|
251 #ifdef _SENDEBUG |
|
252 log.CloseLog(); |
|
253 #endif // _SENDEBUG |
|
254 if( result != KErrServerBusy ) |
|
255 { |
|
256 #ifdef _SENDEBUG |
|
257 log.Write(_L8("- CreateGlobal failed => Another client already starting up SEN.EXE. About to WAIT and RE-CONNECT.")); |
|
258 CleanupStack::PopAndDestroy(); // log.Close() |
|
259 #endif // _SENDEBUG |
|
260 result = KErrServerBusy; // again, this error will activate re-connect loop (max 5 times) |
|
261 } |
|
262 return result; |
|
263 } |
|
264 |
|
265 result = CreateServerProcessL(); |
|
266 if (result != KErrNone) |
|
267 { |
|
268 CleanupStack::PopAndDestroy(); // semaphore.Close() |
|
269 #ifdef _SENDEBUG |
|
270 log.Write(_L8("CreateServerProcessL failed")); |
|
271 log.CloseLog(); |
|
272 CleanupStack::PopAndDestroy(); // log.Close() |
|
273 #endif // _SENDEBUG |
|
274 return result; |
|
275 } |
|
276 |
|
277 // Now start waiting for signal from server: it will release this semaphore from wait: |
|
278 semaphore.Wait(); |
|
279 CleanupStack::PopAndDestroy(); // semaphore.Close() |
|
280 |
|
281 #ifdef _SENDEBUG |
|
282 log.Write(_L("Log file closed.")); |
|
283 log.CloseLog(); |
|
284 CleanupStack::PopAndDestroy(); // log.Close() |
|
285 #endif // _SENDEBUG |
|
286 return KErrNone; |
|
287 } |
|
288 |
|
289 static TInt CreateServerProcessL() |
|
290 { |
|
291 TInt result(KErrNone); |
|
292 |
|
293 #ifdef _SENDEBUG |
|
294 RFileLogger log; |
|
295 CleanupClosePushL(log); |
|
296 User::LeaveIfError( log.Connect() ); |
|
297 // Note: this appends to the log created in StartServer() |
|
298 log.CreateLog(KSenHostletConnectionLogDir, _L("SenStartServer.log"), EFileLoggingModeAppend); |
|
299 log.Write(_L("CreateServerProcessL() invoked by HC.")); |
|
300 #endif // _SENDEBUG |
|
301 |
|
302 const TUidType serverUid(KNullUid, KNullUid, KServerUid3); |
|
303 |
|
304 #if defined(__WINS__) && !defined(EKA2) |
|
305 |
|
306 RLibrary lib; |
|
307 CleanupClosePushL(lib); |
|
308 |
|
309 RThread server; |
|
310 CleanupClosePushL(server); |
|
311 |
|
312 result = lib.Load(KSenServiceManagerFileName, serverUid); |
|
313 |
|
314 if( result == KErrNone ) |
|
315 { |
|
316 #ifdef _SENDEB |
|
317 log.Write(_L8("Library successfully loaded, KErrNone")); |
|
318 #endif // _SENDEBUG |
|
319 |
|
320 // Get the WinsMain function |
|
321 TLibraryFunction functionWinsMain = lib.Lookup(1); |
|
322 |
|
323 // Call it and cast the result to a thread function |
|
324 TThreadFunction serverThreadFunction = |
|
325 reinterpret_cast<TThreadFunction>(functionWinsMain()); |
|
326 |
|
327 TName threadName(KSenServiceManagerFileName); |
|
328 |
|
329 // Append a random number to make it unique |
|
330 threadName.AppendNum(Math::Random(), EHex); |
|
331 |
|
332 |
|
333 result = server.Create(threadName, // create new server thread |
|
334 serverThreadFunction, // thread's main function |
|
335 KDefaultStackSize, |
|
336 NULL, |
|
337 &lib, |
|
338 NULL, |
|
339 KServerMinHeapSize, |
|
340 KServerMaxHeapSize, |
|
341 EOwnerProcess); |
|
342 |
|
343 // if successful, server thread now has the handle to library: |
|
344 |
|
345 if ( result == KErrNone ) |
|
346 { |
|
347 server.SetPriority( EPriorityMore ); |
|
348 } |
|
349 #ifdef _SENDEBUG |
|
350 else |
|
351 { |
|
352 log.Write(_L8("Failed to create server thread.")); |
|
353 } |
|
354 #endif // _SENDEBUG |
|
355 |
|
356 } |
|
357 #ifdef _SENDEBUG |
|
358 else |
|
359 { |
|
360 log.Write(_L8("Could not load library")); |
|
361 } |
|
362 #endif // _SENDEBUG |
|
363 |
|
364 CleanupStack::Pop(); // server (thread) |
|
365 CleanupStack::PopAndDestroy(); // lib |
|
366 CleanupClosePushL(server); |
|
367 |
|
368 #else // NON WINS TARGET(S): |
|
369 RProcess server; |
|
370 CleanupClosePushL(server); |
|
371 result = server.Create(KSenServiceManagerFileName, KNullDesC, serverUid);//CodeScannerWarning |
|
372 #endif |
|
373 |
|
374 if( result == KErrNone ) |
|
375 { |
|
376 #ifdef _SENDEBUG |
|
377 log.Write(_L8("Server successfully created, KErrNone")); |
|
378 #endif // _SENDEBUG |
|
379 server.Resume(); |
|
380 } |
|
381 #ifdef _SENDEBUG |
|
382 else |
|
383 { |
|
384 log.Write(_L8("Could not create server")); |
|
385 } |
|
386 #endif // _SENDEBUG |
|
387 |
|
388 CleanupStack::PopAndDestroy(); // server.Close(); |
|
389 |
|
390 #ifdef _SENDEBUG |
|
391 CleanupStack::PopAndDestroy(); // log.Close(); |
|
392 #endif |
|
393 |
|
394 return result; |
|
395 } |
|
396 |
|
397 |
|
398 // End of file |
|
399 |
|
400 |
|
401 |