|
1 // Copyright (c) 2008-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 "sussimadaptation.h" |
|
17 #include <e32debug.h> |
|
18 |
|
19 /** |
|
20 @internalComponent |
|
21 */ |
|
22 /* |
|
23 //Add aMessage to the queue if AO is busy |
|
24 //else |
|
25 //Store the message in iCurrentMessage so that RunL can call aMessage::Complete() |
|
26 //Unpack params |
|
27 //Submit request |
|
28 */ |
|
29 |
|
30 |
|
31 void CSimAdaptationRequests::SubmitOrQueueL(const RMessage2 &aMessage) |
|
32 { |
|
33 CAdaptationMessage *messageCopy = new(ELeave) CAdaptationMessage(aMessage); |
|
34 |
|
35 if(!IsActive()) |
|
36 { |
|
37 Submit(messageCopy); |
|
38 } |
|
39 else |
|
40 { |
|
41 CleanupStack::PushL(messageCopy); |
|
42 DEBUGPRINT2A("CSimAdaptationRequests queuing request with function id: %d", aMessage.Function()); |
|
43 User::LeaveIfError(iPendingRequestsQueue.Queue(messageCopy)); |
|
44 CleanupStack::Pop(messageCopy); |
|
45 } |
|
46 } |
|
47 |
|
48 void CSimAdaptationRequests::Submit(CAdaptationMessage*& aMessage) |
|
49 { |
|
50 DEBUGPRINT2A("CSimAdaptationRequests immediate submission of request with function id: %d", aMessage->Function()); |
|
51 iCurrentMessage = aMessage; |
|
52 switch(aMessage->Function()) |
|
53 { |
|
54 case EGetSimOwned : |
|
55 { |
|
56 iSimAdaptation.GetSimOwned(iSimOwnedPckg, iStatus); |
|
57 break; |
|
58 } |
|
59 default : |
|
60 { |
|
61 aMessage->Complete(KErrArgument); |
|
62 return; |
|
63 } |
|
64 } |
|
65 SetActive(); |
|
66 } |
|
67 |
|
68 /** |
|
69 CSimAdaptationRequests implements Sim Adaptation related functionality as part of CSsmAdaptationServer. |
|
70 CSsmAdaptationServer loads Sim Adaptation plugin and creates CSimAdaptationRequests using the NewL. |
|
71 From then the loaded Sim Adaptation plugin will be owned by CSimAdaptationRequests. |
|
72 |
|
73 @internalComponent |
|
74 */ |
|
75 CSimAdaptationRequests* CSimAdaptationRequests::NewL(MSimAdaptation& aAdaptation) |
|
76 { |
|
77 CSimAdaptationRequests* self = new(ELeave) CSimAdaptationRequests(aAdaptation); |
|
78 return self; |
|
79 } |
|
80 |
|
81 CSimAdaptationRequests::CSimAdaptationRequests(MSimAdaptation& aAdaptation) : CActive(EPriorityStandard), iSimAdaptation(aAdaptation) |
|
82 { |
|
83 CActiveScheduler::Add(this); |
|
84 } |
|
85 |
|
86 CSimAdaptationRequests::~CSimAdaptationRequests() |
|
87 { |
|
88 iPendingRequestsQueue.NotifyAndRemoveAll(); |
|
89 Cancel(); // This call will delete iCurrentMessage if any |
|
90 iPendingRequestsQueue.Close(); |
|
91 Release(); |
|
92 } |
|
93 |
|
94 void CSimAdaptationRequests::Release() |
|
95 { |
|
96 iSimAdaptation.Release(); |
|
97 } |
|
98 |
|
99 void CSimAdaptationRequests::DoGetSimOwnedL(const RMessage2& aMessage) |
|
100 { |
|
101 SubmitOrQueueL(aMessage); |
|
102 } |
|
103 |
|
104 /* |
|
105 |
|
106 ALGO |
|
107 If iCurrentMessage == aMessage |
|
108 then call plugin's RequestCancel() |
|
109 otherwise |
|
110 search the queue and complete the message with KErrCancel |
|
111 */ |
|
112 |
|
113 void CSimAdaptationRequests::DoGetSimCancel(const RMessage2& aMessage) |
|
114 { |
|
115 |
|
116 if(iCurrentMessage != NULL) |
|
117 { |
|
118 if(aMessage.Session() == iCurrentMessage->Session()) |
|
119 { |
|
120 DEBUGPRINT1A("CSimAdaptationRequests cancelling current request as requested"); |
|
121 iSimAdaptation.GetCancel(); |
|
122 } |
|
123 iPendingRequestsQueue.RemoveFromQueueAndComplete(aMessage); |
|
124 aMessage.Complete(KErrNone); |
|
125 } |
|
126 else |
|
127 { |
|
128 DEBUGPRINT1A("CSimAdaptationRequests nothing to cancel, but cancel requested"); |
|
129 aMessage.Complete(KErrNone); |
|
130 } |
|
131 |
|
132 } |
|
133 |
|
134 /** |
|
135 * Returns the SIM adaptation in use by this object |
|
136 * |
|
137 * @internalComponent |
|
138 */ |
|
139 MSimAdaptation& CSimAdaptationRequests::Adaptation() |
|
140 { |
|
141 return iSimAdaptation; |
|
142 } |
|
143 |
|
144 void CSimAdaptationRequests::RunL() |
|
145 { |
|
146 |
|
147 WriteResponseDataToClientMessageL(); |
|
148 |
|
149 DEBUGPRINT2A("CSimAdaptationRequests processed the request with funtion id: %d", iCurrentMessage->Function()); |
|
150 iCurrentMessage->Complete(iStatus.Int()); |
|
151 delete iCurrentMessage; |
|
152 iCurrentMessage = NULL; |
|
153 |
|
154 if( (iPendingRequestsQueue.IsEmpty()) == EFalse ) |
|
155 { |
|
156 CAdaptationMessage *messageCopy = NULL; |
|
157 iPendingRequestsQueue.Dequeue(messageCopy); |
|
158 Submit(messageCopy); |
|
159 } |
|
160 } |
|
161 |
|
162 void CSimAdaptationRequests::WriteResponseDataToClientMessageL() |
|
163 { |
|
164 switch(iCurrentMessage->Function()) |
|
165 { |
|
166 case EGetSimOwned: |
|
167 { |
|
168 iCurrentMessage->WriteL(0,iSimOwnedPckg); |
|
169 break; |
|
170 } |
|
171 default: |
|
172 { |
|
173 break; |
|
174 } |
|
175 } |
|
176 } |
|
177 TInt CSimAdaptationRequests::RunError( TInt aError ) |
|
178 { |
|
179 |
|
180 if(iCurrentMessage != NULL) |
|
181 { |
|
182 iCurrentMessage->Complete(aError); |
|
183 delete iCurrentMessage; |
|
184 iCurrentMessage = NULL; |
|
185 } |
|
186 |
|
187 while( (iPendingRequestsQueue.IsEmpty()) == EFalse ) |
|
188 { |
|
189 iPendingRequestsQueue.Dequeue(iCurrentMessage); |
|
190 iCurrentMessage->Complete(aError); |
|
191 delete iCurrentMessage; |
|
192 iCurrentMessage = NULL; |
|
193 } |
|
194 |
|
195 return KErrNone; |
|
196 } |
|
197 |
|
198 void CSimAdaptationRequests::DoCancel() |
|
199 { |
|
200 if(iCurrentMessage != NULL) |
|
201 { |
|
202 iCurrentMessage->Complete(KErrCancel); |
|
203 delete iCurrentMessage; |
|
204 iCurrentMessage = NULL; |
|
205 } |
|
206 |
|
207 while( (iPendingRequestsQueue.IsEmpty()) == EFalse ) |
|
208 { |
|
209 iPendingRequestsQueue.Dequeue(iCurrentMessage); |
|
210 iCurrentMessage->Complete(KErrCancel); |
|
211 delete iCurrentMessage; |
|
212 iCurrentMessage = NULL; |
|
213 } |
|
214 |
|
215 } |
|
216 |
|
217 // class CSimAdaptationObservers |
|
218 CSimAdaptationObservers* CSimAdaptationObservers::NewL(MSimAdaptation& aAdaptation) |
|
219 { |
|
220 CSimAdaptationObservers* self = new(ELeave) CSimAdaptationObservers(aAdaptation); |
|
221 |
|
222 CleanupStack::PushL(self); |
|
223 CleanupStack::Pop(); // self |
|
224 return self; |
|
225 } |
|
226 |
|
227 CSimAdaptationObservers::CSimAdaptationObservers(MSimAdaptation& aAdaptation) : CActive(EPriorityStandard), iSimAdaptation(aAdaptation) |
|
228 { |
|
229 CActiveScheduler::Add(this); |
|
230 } |
|
231 |
|
232 CSimAdaptationObservers::~CSimAdaptationObservers() |
|
233 { |
|
234 Cancel(); |
|
235 iObserversList.Close(); |
|
236 } |
|
237 |
|
238 void CSimAdaptationObservers::DoGetLastSimEvent(const RMessage2& aMessage) |
|
239 { |
|
240 TRAPD(err,aMessage.WriteL(0, iEventPckg)); |
|
241 aMessage.Complete(err); |
|
242 } |
|
243 |
|
244 void CSimAdaptationObservers::DoNotifySimEventL(const RMessage2& aMessage) |
|
245 { |
|
246 if(iObserversList.Count() == 0) |
|
247 { |
|
248 // First observer so start notification |
|
249 StartNotification(); |
|
250 } |
|
251 CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage); |
|
252 CleanupStack::PushL(newObserver); |
|
253 iObserversList.AddObserverL(newObserver); |
|
254 CleanupStack::Pop();//newObserver |
|
255 } |
|
256 |
|
257 void CSimAdaptationObservers::DoNotifySimEventCancelL(const RMessage2& aMessage) |
|
258 { |
|
259 iSimAdaptation.NotifyCancel(); |
|
260 CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage); |
|
261 iObserversList.RemoveObserver(newObserver); |
|
262 aMessage.Complete(KErrNone); |
|
263 |
|
264 if(iObserversList.Count() == 0) |
|
265 { |
|
266 // Last observer cancelled, stop notification |
|
267 if(IsActive()) |
|
268 { |
|
269 Cancel(); |
|
270 } |
|
271 } |
|
272 } |
|
273 |
|
274 void CSimAdaptationObservers::StartNotification() |
|
275 { |
|
276 DEBUGPRINT1A("CSimAdaptationObservers starting request for event notification"); |
|
277 iSimAdaptation.NotifySimEvent(iEventPckg,iStatus); |
|
278 |
|
279 SetActive(); |
|
280 } |
|
281 |
|
282 void CSimAdaptationObservers::RunL() |
|
283 { |
|
284 DEBUGPRINT1A("CSimAdaptationObservers received event notification"); |
|
285 iObserversList.NotifyAndRemoveAll(iEventPckg(),iStatus.Int()); |
|
286 } |
|
287 |
|
288 TInt CSimAdaptationObservers::RunError( TInt /*aError */) |
|
289 { |
|
290 iObserversList.Close(); |
|
291 return KErrNone; |
|
292 } |
|
293 |
|
294 void CSimAdaptationObservers::DoCancel() |
|
295 { |
|
296 DEBUGPRINT1A("CSimAdaptationObservers cancelling request for event notification"); |
|
297 iSimAdaptation.NotifyCancel(); |
|
298 iObserversList.NotifyAndRemoveAll(iEventPckg(), KErrCancel); |
|
299 } |
|
300 |
|
301 //Observer related functionality |
|
302 void RSimAdaptationObserversList::AddObserverL(CAdaptationMessage *aNotificationMessage) |
|
303 { |
|
304 //any error will cause a leave |
|
305 iObservers.AppendL(aNotificationMessage); |
|
306 } |
|
307 void RSimAdaptationObserversList::Close() |
|
308 { |
|
309 // Notify all clients first |
|
310 NotifyAndRemoveAll(static_cast<TSsmSimEventType>(0), KErrCancel); |
|
311 // Call RArray close() |
|
312 iObservers.Close(); |
|
313 } |
|
314 |
|
315 TInt RSimAdaptationObserversList::Count() |
|
316 { |
|
317 return iObservers.Count(); |
|
318 } |
|
319 |
|
320 void RSimAdaptationObserversList::NotifyAndRemoveAll(TSsmSimEventType aEventType,TInt aCompleteCode) |
|
321 { |
|
322 TInt index,count = iObservers.Count(); |
|
323 |
|
324 for(index =0;index < count ;index++) |
|
325 { |
|
326 TPckgBuf<TSsmSimEventType> pckgEvType(aEventType); |
|
327 |
|
328 // Complete the client with the requested code unless |
|
329 // the descriptor write fails |
|
330 TInt completeCode = aCompleteCode; |
|
331 // Only copy across the event type if it was successful |
|
332 if(aCompleteCode == KErrNone) |
|
333 { |
|
334 TRAPD(err,iObservers[index]->WriteL(0,pckgEvType)); |
|
335 if(err != KErrNone) |
|
336 { |
|
337 completeCode = err; |
|
338 } |
|
339 } |
|
340 iObservers[index]->Complete(completeCode); |
|
341 delete iObservers[index]; |
|
342 iObservers[index] = NULL; |
|
343 } |
|
344 iObservers.Reset(); |
|
345 } |
|
346 /* |
|
347 ALGO |
|
348 //parse TRequestStatus from each CAdaptationMessage and |
|
349 //Find or FindL |
|
350 //Index will be returned |
|
351 //then call Remove() with Index in the array |
|
352 */ |
|
353 |
|
354 void RSimAdaptationObserversList::RemoveObserver(CAdaptationMessage *aCancelMessage) |
|
355 { |
|
356 if(aCancelMessage == NULL) |
|
357 { |
|
358 return; |
|
359 } |
|
360 TInt index,count = iObservers.Count(); |
|
361 CAdaptationMessage *notificationMessage; |
|
362 |
|
363 for(index =0; index < count; index++) |
|
364 { |
|
365 notificationMessage = iObservers[index]; |
|
366 |
|
367 // Compare on session pointers to check that the cancel only happens to notifications from the |
|
368 // same session |
|
369 if( notificationMessage->Session() == aCancelMessage->Session()) |
|
370 { |
|
371 CAdaptationMessage *message= iObservers[index]; |
|
372 iObservers[index]->Complete(KErrCancel); |
|
373 iObservers.Remove(index); |
|
374 delete message; |
|
375 break; |
|
376 } |
|
377 } |
|
378 delete aCancelMessage; |
|
379 } |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |