|
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 |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <ecom/ecom.h> |
|
21 #include "HWRMPluginHandler.h" |
|
22 #include "HWRMClientServer.h" |
|
23 #include "HWRMService.h" |
|
24 #include "HWRMtrace.h" |
|
25 |
|
26 |
|
27 // EXTERNAL DATA STRUCTURES |
|
28 // None |
|
29 |
|
30 // EXTERNAL FUNCTION PROTOTYPES |
|
31 // None |
|
32 |
|
33 // CONSTANTS |
|
34 // None |
|
35 |
|
36 // MACROS |
|
37 // None |
|
38 |
|
39 // LOCAL CONSTANTS AND MACROS |
|
40 _LIT( KPanicCategory, "HWRMPluginHandler" ); |
|
41 |
|
42 // MODULE DATA STRUCTURES |
|
43 // None |
|
44 |
|
45 // LOCAL FUNCTION PROTOTYPES |
|
46 // None |
|
47 |
|
48 // FORWARD DECLARATIONS |
|
49 // None |
|
50 |
|
51 // ============================= LOCAL FUNCTIONS =============================== |
|
52 |
|
53 // ============================ MEMBER FUNCTIONS =============================== |
|
54 |
|
55 // ----------------------------------------------------------------------------- |
|
56 // CHWRMPluginHandler::CHWRMPluginHandler |
|
57 // C++ constructor |
|
58 // ----------------------------------------------------------------------------- |
|
59 // |
|
60 CHWRMPluginHandler::CHWRMPluginHandler(TInt aRequestTimeout) |
|
61 : iPlugin(NULL), |
|
62 iTransIdCounter(0), |
|
63 iTransactionList(NULL), |
|
64 iPluginTimer(NULL), |
|
65 iRequestTimeout(aRequestTimeout) |
|
66 { |
|
67 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CHWRMPluginHandler()" )); |
|
68 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CHWRMPluginHandler - return " )); |
|
69 } |
|
70 |
|
71 // ----------------------------------------------------------------------------- |
|
72 // CHWRMPluginHandler::ConstructL |
|
73 // 2nd phase constructor gets plugin instance. |
|
74 // ----------------------------------------------------------------------------- |
|
75 // |
|
76 void CHWRMPluginHandler::ConstructL(const TDesC8& aMatch) |
|
77 { |
|
78 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ConstructL(<aMatch>)" )); |
|
79 |
|
80 // get plugin instance |
|
81 iPlugin = CHWRMPluginService::NewL(aMatch, this); |
|
82 iTransactionList = CHWRMPluginTransactionList::NewL(); |
|
83 iPluginTimer = CHWRMGenericTimer::NewL(*this, iRequestTimeout, 0); |
|
84 |
|
85 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ConstructL - return" )); |
|
86 } |
|
87 |
|
88 // ----------------------------------------------------------------------------- |
|
89 // CHWRMPluginHandler::NewL |
|
90 // Two-phased constructor. |
|
91 // ----------------------------------------------------------------------------- |
|
92 // |
|
93 CHWRMPluginHandler* CHWRMPluginHandler::NewL(const TDesC8& aMatch, TInt aRequestTimeout) |
|
94 { |
|
95 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::NewL(<aMatch>)" ) ); |
|
96 |
|
97 CHWRMPluginHandler* self = new( ELeave ) CHWRMPluginHandler(aRequestTimeout); |
|
98 |
|
99 CleanupStack::PushL( self ); |
|
100 self->ConstructL(aMatch); |
|
101 CleanupStack::Pop(); |
|
102 |
|
103 COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::NewL - return 0x%x" ), self ); |
|
104 |
|
105 return self; |
|
106 } |
|
107 |
|
108 // --------------------------------------------------------- |
|
109 // Destructor |
|
110 // --------------------------------------------------------- |
|
111 // |
|
112 CHWRMPluginHandler::~CHWRMPluginHandler() |
|
113 { |
|
114 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler()" ) ); |
|
115 |
|
116 delete iPluginTimer; |
|
117 |
|
118 if ( iPlugin ) |
|
119 { |
|
120 // Cancel any ongoing requests |
|
121 while ( iTransactionList->GetFirstItem() ) |
|
122 { |
|
123 COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler - Canceling transaction %d" ), iTransactionList->GetFirstItem()->iTransId ); |
|
124 TRAPD(err, CancelCommandL(iTransactionList->GetFirstItem()->iTransId)); |
|
125 if ( err != KErrNone ) |
|
126 { |
|
127 COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler - Canceling transaction %d failed" ), iTransactionList->GetFirstItem()->iTransId ); |
|
128 } |
|
129 } |
|
130 |
|
131 delete iPlugin; |
|
132 iPlugin = NULL; |
|
133 } |
|
134 |
|
135 // delete transaction list |
|
136 delete iTransactionList; |
|
137 |
|
138 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler - return " )); |
|
139 } |
|
140 |
|
141 // ----------------------------------------------------------------------------- |
|
142 // CHWRMPluginHandler::ProcessCommandL |
|
143 // Handles plugin requests from sessions. |
|
144 // Only one concurrent request is supported. |
|
145 // ----------------------------------------------------------------------------- |
|
146 // |
|
147 TUint8 CHWRMPluginHandler::ProcessCommandL( TInt aCommandId, |
|
148 TDesC8& aData, |
|
149 CHWRMService* aCompletionCallback ) |
|
150 { |
|
151 COMPONENT_TRACE3(_L( "HWRM Server - CHWRMPluginHandler::ProcessCommandL(0x%x, <aData>, 0x%x)" ), aCommandId, aCompletionCallback ); |
|
152 |
|
153 __ASSERT_ALWAYS(iPlugin, User::Panic(KPanicCategory, EPanicBadHandle)); |
|
154 |
|
155 // Generate new transaction ID. |
|
156 iTransIdCounter++; |
|
157 if ( iTransIdCounter == 0 ) |
|
158 { |
|
159 // Counter will overflow back to zero when it hits max. |
|
160 // However, zero indicates completed transaction as return value, so |
|
161 // increase counter again. |
|
162 iTransIdCounter++; |
|
163 } |
|
164 |
|
165 // If we run out of transIds, return server is busy. |
|
166 if ( iTransactionList->FindTransaction(iTransIdCounter, EFalse) ) |
|
167 { |
|
168 User::Leave(KErrServerBusy); |
|
169 } |
|
170 |
|
171 // Create transaction data before call in case it leaves |
|
172 TTime obsoletionTime; |
|
173 obsoletionTime.UniversalTime(); |
|
174 obsoletionTime += iRequestTimeout; |
|
175 THWRMTransactionData* data = new(ELeave) THWRMTransactionData(aCompletionCallback, iTransIdCounter, aCommandId, obsoletionTime); |
|
176 |
|
177 // Push transaction data to cleanup stack so that it will clean out if ProcessCommandL leaves. |
|
178 CleanupStack::PushL( data ); |
|
179 |
|
180 iPlugin->ProcessCommandL( aCommandId, data->iTransId, aData ); |
|
181 |
|
182 TUint8 retval(0); |
|
183 |
|
184 // data still needed, do not destroy, just pop |
|
185 CleanupStack::Pop( data ); |
|
186 |
|
187 // Add data to list |
|
188 iTransactionList->AddTransaction( data ); |
|
189 |
|
190 retval = data->iTransId; |
|
191 |
|
192 // Start timer if it is not already started |
|
193 if ( !iPluginTimer->IsActive()) |
|
194 { |
|
195 iPluginTimer->Set(iRequestTimeout); |
|
196 } |
|
197 |
|
198 COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::ProcessCommandL - return 0x%x" ), retval ); |
|
199 |
|
200 return retval; |
|
201 |
|
202 } |
|
203 |
|
204 // ----------------------------------------------------------------------------- |
|
205 // CHWRMPluginHandler::CancelCommandL |
|
206 // Cancels the currently executing request |
|
207 // ----------------------------------------------------------------------------- |
|
208 // |
|
209 void CHWRMPluginHandler::CancelCommandL( TUint8 aTransId ) |
|
210 { |
|
211 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL()" )); |
|
212 |
|
213 __ASSERT_ALWAYS(iPlugin, User::Panic(KPanicCategory, EPanicBadHandle)); |
|
214 |
|
215 // Find correct transaction data and remove it from list |
|
216 THWRMTransactionData* data = static_cast<THWRMTransactionData*>(iTransactionList->FindTransaction(aTransId, ETrue)); |
|
217 |
|
218 // cancel request timer if no more transactions open |
|
219 if ( iTransactionList->Count() == 0 ) |
|
220 { |
|
221 iPluginTimer->Cancel(); |
|
222 } |
|
223 |
|
224 // If transaction is not open, do nothing |
|
225 // Do not cancel if request has no callback (i.e. final destructor state restorings) |
|
226 // (these are canceled by timeout if they do not complete successfully) |
|
227 if ( data && data->iCompletionCallback ) |
|
228 { |
|
229 CleanupStack::PushL( data ); |
|
230 |
|
231 iPlugin->CancelCommandL( data->iTransId, data->iCommandId ); |
|
232 |
|
233 // Destroy the transaction data, since transaction is over. |
|
234 CleanupStack::PopAndDestroy( data ); |
|
235 data = NULL; |
|
236 } |
|
237 else |
|
238 { |
|
239 TTime now; |
|
240 now.UniversalTime(); |
|
241 if ( data && data->iObsoletionTime >= now ) |
|
242 { |
|
243 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL - Not cancelled because no callback" ) ); |
|
244 |
|
245 // Push data back to list |
|
246 iTransactionList->AddTransaction( data ); |
|
247 } |
|
248 else |
|
249 { |
|
250 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL - Cancelled because command was obsolete" ) ); |
|
251 } |
|
252 } |
|
253 |
|
254 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL - return" ) ); |
|
255 } |
|
256 |
|
257 // ----------------------------------------------------------------------------- |
|
258 // CHWRMPluginHandler::ProcessResponseL |
|
259 // Routes response from plugin to correct service instance |
|
260 // ----------------------------------------------------------------------------- |
|
261 // |
|
262 void CHWRMPluginHandler::ProcessResponseL( TInt aCommandId, |
|
263 TUint8 aTransId, |
|
264 TDesC8& aData ) |
|
265 { |
|
266 COMPONENT_TRACE3(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL(0x%x, 0x%x, <aData> )" ), aCommandId, aTransId ); |
|
267 |
|
268 // Find and remove correct transaction data and remove it from queue |
|
269 THWRMTransactionData* data = static_cast<THWRMTransactionData*>(iTransactionList->FindTransaction(aTransId, ETrue)); |
|
270 |
|
271 // cancel request timer if no more transactions open |
|
272 if ( iTransactionList->Count() == 0 ) |
|
273 { |
|
274 iPluginTimer->Cancel(); |
|
275 } |
|
276 |
|
277 // If transaction is not open, response not expected. |
|
278 if ( data ) |
|
279 { |
|
280 CleanupStack::PushL( data ); |
|
281 |
|
282 // Check that command ID is the expected one |
|
283 if ( data->iCommandId != aCommandId ) |
|
284 { |
|
285 COMPONENT_TRACE3(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL - Command ID mismatch, expected: 0x%x, got 0x%x" ), data->iCommandId, aCommandId ); |
|
286 User::Leave(KErrBadHandle); |
|
287 } |
|
288 |
|
289 // Route data to callback service if one is needed |
|
290 if ( data->iCompletionCallback ) |
|
291 { |
|
292 data->iCompletionCallback->ProcessResponseL(aCommandId, aTransId, aData, EFalse); |
|
293 } |
|
294 |
|
295 CleanupStack::PopAndDestroy( data ); |
|
296 data = NULL; |
|
297 } |
|
298 else |
|
299 { |
|
300 // There is problem in adaptation, as unexpected transaction was completed. |
|
301 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL - No transaction data found!" ) ); |
|
302 User::Leave(KErrBadHandle); |
|
303 } |
|
304 |
|
305 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL - return" ) ); |
|
306 } |
|
307 |
|
308 // ----------------------------------------------------------------------------- |
|
309 // CHWRMPluginHandler::EventL |
|
310 // Routes indication from plugin to correct indication handler |
|
311 // ----------------------------------------------------------------------------- |
|
312 // |
|
313 void CHWRMPluginHandler::EventL( const TUint32 aIndId, TDesC8& aData ) |
|
314 { |
|
315 COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::EventL(), Count() = %d" ), iIndicationCallbacks.Count() ); |
|
316 |
|
317 for (TUint i=0; i<iIndicationCallbacks.Count(); i++) |
|
318 { |
|
319 MHWRMIndicationHandler* pHandler = iIndicationCallbacks[i]; |
|
320 |
|
321 COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::EventL(), callback %d" ), i ); |
|
322 pHandler->ProcessIndicationL(aIndId, aData); |
|
323 } |
|
324 } |
|
325 |
|
326 // ----------------------------------------------------------------------------- |
|
327 // CHWRMPluginHandler::RegisterForIndications |
|
328 // Registers a handler for receiving HWRM plug-in indications |
|
329 // ----------------------------------------------------------------------------- |
|
330 // |
|
331 void CHWRMPluginHandler::RegisterForIndications(MHWRMIndicationHandler* aCallback) |
|
332 { |
|
333 COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::RegisterForIndications(), Count() = %d" ), iIndicationCallbacks.Count() ); |
|
334 |
|
335 iIndicationCallbacks.Append(aCallback); |
|
336 } |
|
337 |
|
338 // ----------------------------------------------------------------------------- |
|
339 // CHWRMPluginHandler::DeregisterForIndications |
|
340 // Deregisters handlers for receiving HWRM plug-in indications |
|
341 // ----------------------------------------------------------------------------- |
|
342 // |
|
343 void CHWRMPluginHandler::DeregisterForIndications(MHWRMIndicationHandler* aCallback) |
|
344 { |
|
345 COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::DeregisterForIndications(), Count() = %d" ), iIndicationCallbacks.Count() ); |
|
346 |
|
347 TInt findErr = iIndicationCallbacks.Find(aCallback); |
|
348 COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::DeregisterForIndications(), findErr = %d" ), findErr ); |
|
349 |
|
350 if ( findErr != KErrNotFound ) |
|
351 { |
|
352 iIndicationCallbacks.Remove(findErr); |
|
353 COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::DeregisterForIndications(), item removed, Count() = %d" ), iIndicationCallbacks.Count() ); |
|
354 } |
|
355 } |
|
356 |
|
357 // ----------------------------------------------------------------------------- |
|
358 // CHWRMPluginHandler::GenericTimerFired |
|
359 // Cancels all obsolete transactions. TimerId is irrelevant as only one timer. |
|
360 // ----------------------------------------------------------------------------- |
|
361 // |
|
362 void CHWRMPluginHandler::GenericTimerFired(TInt /*aTimerId*/, TBool /*aCutOff*/) |
|
363 { |
|
364 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired()" ) ); |
|
365 |
|
366 __ASSERT_ALWAYS(iPlugin, User::Panic(KPanicCategory, EPanicBadHandle)); |
|
367 |
|
368 // Since requests are added to end of list always, they are in order of obsolescense. |
|
369 // Cancel requests that are obsolete and notify callback service |
|
370 TInt err(KErrNone); |
|
371 TTime now; |
|
372 now.UniversalTime(); |
|
373 THWRMTransactionData* data = static_cast<THWRMTransactionData*>(iTransactionList->GetFirstItem()); |
|
374 |
|
375 while ( data && ( data->iObsoletionTime < now ) ) |
|
376 { |
|
377 COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - Canceling obsolete transaction 0x%x" ), data->iTransId ); |
|
378 |
|
379 // Cancel transaction. |
|
380 TRAP(err, iPlugin->CancelCommandL( data->iTransId, data->iCommandId )); |
|
381 if ( err != KErrNone ) |
|
382 { |
|
383 // Ignore errors as we cannot do anything about it anyway. Just trace. |
|
384 COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - Canceling obsolete transaction FAILED (%d)!" ), err ); |
|
385 } |
|
386 |
|
387 // Notify service that request was canceled by timeout |
|
388 if ( data->iCompletionCallback ) |
|
389 { |
|
390 TBuf8<1> emptyDes; |
|
391 TRAP(err, data->iCompletionCallback->ProcessResponseL(data->iCommandId, data->iTransId, emptyDes, ETrue)); |
|
392 if ( err != KErrNone ) |
|
393 { |
|
394 // Ignore errors as we cannot do anything about it anyway. Just trace. |
|
395 COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - Notifying obsolete transaction cancel FAILED (%d)!" ), err ); |
|
396 } |
|
397 } |
|
398 |
|
399 // Destroy the transaction data, since transaction is over. |
|
400 iTransactionList->RemoveFirstItem(); |
|
401 delete data; |
|
402 data = NULL; |
|
403 |
|
404 // get next data to check |
|
405 data = static_cast<THWRMTransactionData*>(iTransactionList->GetFirstItem()); |
|
406 } |
|
407 |
|
408 // Restart timer if there is more transactions in list |
|
409 if ( data ) |
|
410 { |
|
411 iPluginTimer->Set(iRequestTimeout); |
|
412 } |
|
413 |
|
414 COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - return" ) ); |
|
415 } |
|
416 |
|
417 |
|
418 // ========================== OTHER EXPORTED FUNCTIONS ========================= |
|
419 |
|
420 // End of File |