|
1 /* |
|
2 * Copyright (c) 2009 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 // Include Files |
|
20 #include <e32base.h> |
|
21 #include <f32file.h> |
|
22 #include "STFLogServer.h" |
|
23 #include "STFLoggerCSCommon.h" |
|
24 |
|
25 |
|
26 // Called by the CServer framework |
|
27 void CSTFLogSession::CreateL() |
|
28 { |
|
29 CSTFLogServer* server = static_cast<CSTFLogServer*>(const_cast<CServer2*>(Server())); |
|
30 ASSERT(server); |
|
31 server->AddSession(); |
|
32 iLogger = NULL; |
|
33 } |
|
34 |
|
35 CSTFLogSession::~CSTFLogSession() |
|
36 { |
|
37 CSTFLogServer* server = static_cast<CSTFLogServer*>(const_cast<CServer2*>(Server())); |
|
38 ASSERT(server); |
|
39 server->RemoveSession(); |
|
40 |
|
41 if(iLogger) |
|
42 { |
|
43 delete iLogger; |
|
44 iLogger = 0; |
|
45 } |
|
46 } |
|
47 |
|
48 // Handle a client request |
|
49 // Leaves are handled by CHerculeanSession::ServiceError() |
|
50 void CSTFLogSession::ServiceL(const RMessage2& aMessage) |
|
51 { |
|
52 switch (aMessage.Function()) |
|
53 { |
|
54 case (ESTFLogger_CreateLogger): |
|
55 CreateLogger(aMessage); |
|
56 break; |
|
57 case (ESTFLogger_Log_TInt_TDesC): |
|
58 Log_TInt_TDesCL(aMessage); |
|
59 break; |
|
60 case (ESTFLogger_Log_TInt_TDesC8): |
|
61 Log_TInt_TDesC8L(aMessage); |
|
62 break; |
|
63 case (ESTFLogger_CreationResult): |
|
64 CreationResult(aMessage); |
|
65 break; |
|
66 case (ESTFLogger_OutputType): |
|
67 OutputType(aMessage); |
|
68 break; |
|
69 default: |
|
70 PanicClient(aMessage,EPanicNotSupported); |
|
71 break; |
|
72 } |
|
73 } |
|
74 |
|
75 // Handles leaves from CSTFLogSession::ServiceL() |
|
76 // A bad descriptor error implies a badly programmed client, so panic it |
|
77 // Report other errors to the client by completing the outstanding request with the error |
|
78 |
|
79 void CSTFLogSession::ServiceError(const RMessage2& aMessage, TInt aError) |
|
80 { |
|
81 if (KErrBadDescriptor==aError) |
|
82 PanicClient(aMessage,EPanicBadDescriptor); |
|
83 else |
|
84 aMessage.Complete(aError); |
|
85 } |
|
86 |
|
87 |
|
88 void CSTFLogSession::CreateLogger(const RMessage2& aMessage) |
|
89 { |
|
90 TSTFLoggerCreateData loggerCreateData; |
|
91 TPckg<TSTFLoggerCreateData> pckgData(loggerCreateData); |
|
92 aMessage.Read(0,pckgData); |
|
93 TInt err; |
|
94 if(!iLogger) |
|
95 { |
|
96 TRAP(err, iLogger = CStifLoggerBase::NewL( loggerCreateData.iTestPath, |
|
97 loggerCreateData.iTestFile, |
|
98 loggerCreateData.iLoggerType, |
|
99 loggerCreateData.iOutput, |
|
100 loggerCreateData.iOverWrite, |
|
101 loggerCreateData.iWithTimeStamp, |
|
102 loggerCreateData.iWithLineBreak, |
|
103 loggerCreateData.iWithEventRanking, |
|
104 loggerCreateData.iThreadIdToLogFile, |
|
105 loggerCreateData.iCreateLogDir, |
|
106 loggerCreateData.iStaticBufferSize, |
|
107 loggerCreateData.iUnicode, |
|
108 loggerCreateData.iThreadId) ); |
|
109 } |
|
110 aMessage.Complete(err); |
|
111 } |
|
112 |
|
113 void CSTFLogSession::Log_TInt_TDesCL(const RMessage2& aMessage) |
|
114 { |
|
115 if(!iLogger) |
|
116 { |
|
117 aMessage.Complete(KErrBadHandle); |
|
118 } |
|
119 else |
|
120 { |
|
121 TInt length = aMessage.Int0(); |
|
122 TInt style = aMessage.Int1(); |
|
123 RBuf buf; |
|
124 buf.CleanupClosePushL(); |
|
125 buf.Create(length); |
|
126 aMessage.Read(2, buf); |
|
127 TInt err = iLogger->Log(style, buf); |
|
128 CleanupStack::PopAndDestroy(&buf); |
|
129 aMessage.Complete(err); |
|
130 } |
|
131 } |
|
132 void CSTFLogSession::Log_TInt_TDesC8L(const RMessage2& aMessage) |
|
133 { |
|
134 if(!iLogger) |
|
135 { |
|
136 aMessage.Complete(KErrBadHandle); |
|
137 } |
|
138 else |
|
139 { |
|
140 TInt length = aMessage.Int0(); |
|
141 TInt style = aMessage.Int1(); |
|
142 RBuf8 buf8; |
|
143 buf8.CleanupClosePushL(); |
|
144 buf8.Create(length); |
|
145 aMessage.Read(2, buf8); |
|
146 TInt err = iLogger->Log(style, buf8); |
|
147 CleanupStack::PopAndDestroy(&buf8); |
|
148 aMessage.Complete(err); |
|
149 } |
|
150 } |
|
151 |
|
152 void CSTFLogSession::CreationResult(const RMessage2& aMessage) |
|
153 { |
|
154 if(!iLogger) |
|
155 { |
|
156 aMessage.Complete(KErrBadHandle); |
|
157 } |
|
158 else |
|
159 { |
|
160 TInt result; |
|
161 TPckg<TInt> creationResult(result); |
|
162 result = iLogger->CreationResult(); |
|
163 |
|
164 aMessage.Write(0,creationResult); |
|
165 aMessage.Complete(KErrNone); |
|
166 } |
|
167 |
|
168 } |
|
169 void CSTFLogSession::OutputType(const RMessage2& aMessage) |
|
170 { |
|
171 if(!iLogger) |
|
172 { |
|
173 aMessage.Complete(KErrBadHandle); |
|
174 } |
|
175 else |
|
176 { |
|
177 CStifLogger::TOutput outputType; |
|
178 TPckg<CStifLogger::TOutput> type(outputType); |
|
179 outputType = iLogger->OutputType(); |
|
180 |
|
181 aMessage.Write(0,type); |
|
182 aMessage.Complete(KErrNone); |
|
183 } |
|
184 } |
|
185 |
|
186 CServer2* CSTFLogServer::NewLC() |
|
187 { |
|
188 CSTFLogServer* self=new(ELeave) CSTFLogServer; |
|
189 CleanupStack::PushL(self); |
|
190 self->ConstructL(); |
|
191 return self; |
|
192 } |
|
193 |
|
194 // Starts the server and constructs the shutdown object, starting the timer to ensure that |
|
195 // the server will exit even if the starting client connection fails |
|
196 void CSTFLogServer::ConstructL() |
|
197 { |
|
198 StartL(KSTFLoggerServerName); |
|
199 iShutdown.ConstructL(); |
|
200 iShutdown.Start(); |
|
201 } |
|
202 |
|
203 // Example doesn't bother checking the version |
|
204 CSession2* CSTFLogServer::NewSessionL(const TVersion& /*aVersion*/,const RMessage2& /*aMessage*/) const |
|
205 { |
|
206 return new(ELeave) CSTFLogSession(); |
|
207 } |
|
208 // Cancel the shutdown timer now, the new session is connected |
|
209 void CSTFLogServer::AddSession() |
|
210 { |
|
211 ++iSessionCount; |
|
212 iShutdown.Cancel(); // Cancel any outstanding shutdown timer |
|
213 } |
|
214 |
|
215 // Decrement the session counter and start the shutdown timer if the last client has disconnected |
|
216 void CSTFLogServer::RemoveSession() |
|
217 { |
|
218 if (--iSessionCount==0) |
|
219 iShutdown.Start(); |
|
220 } |
|
221 |
|
222 // Initiates server exit when the timer expires |
|
223 void CShutdown::RunL() |
|
224 { |
|
225 CActiveScheduler::Stop(); |
|
226 } |
|
227 |
|
228 void PanicClient(const RMessage2& aMessage,TServerPanic aPanic) |
|
229 { |
|
230 _LIT(KPanic,"STFLoggingServer"); |
|
231 aMessage.Panic(KPanic,aPanic); |
|
232 } |
|
233 |
|
234 // Initialize and run the server |
|
235 static void RunTheServerL() |
|
236 {// First create and install the active scheduler |
|
237 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler; |
|
238 CleanupStack::PushL(scheduler); |
|
239 CActiveScheduler::Install(scheduler); |
|
240 |
|
241 // create the server |
|
242 CSTFLogServer::NewLC(); |
|
243 |
|
244 // Naming the server thread after the server helps to debug panics |
|
245 User::LeaveIfError(User::RenameThread(KSTFLoggerServerName)); |
|
246 |
|
247 RProcess::Rendezvous(KErrNone); |
|
248 |
|
249 // Enter the wait loop |
|
250 CActiveScheduler::Start(); |
|
251 |
|
252 // Exited - cleanup the server and scheduler |
|
253 CleanupStack::PopAndDestroy(2, scheduler); |
|
254 } |
|
255 |
|
256 // Server process entry-point |
|
257 TInt E32Main() |
|
258 { |
|
259 __UHEAP_MARK; // Heap checking |
|
260 |
|
261 CTrapCleanup* cleanup=CTrapCleanup::New(); |
|
262 TInt r=KErrNoMemory; |
|
263 if (cleanup) |
|
264 { |
|
265 TRAP(r,RunTheServerL()); |
|
266 delete cleanup; |
|
267 } |
|
268 __UHEAP_MARKEND; |
|
269 return r; |
|
270 } |