|
1 // Copyright (c) 2005-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 // This is part of an ECOM plug-in |
|
15 // |
|
16 // |
|
17 |
|
18 #include <ss_std.h> |
|
19 #include "shimnifmansconn.h" |
|
20 #include "es_prot.h" |
|
21 |
|
22 |
|
23 /** |
|
24 @internalComponent |
|
25 */ |
|
26 const TUint KMicrosecondsInASecond = 1000000; |
|
27 const TInt KMaxTimerPeriod = KMaxTInt32/KMicrosecondsInASecond; //< max period of a CTimer using After() |
|
28 |
|
29 |
|
30 CSubConnectionLinkShimClient::CSubConnectionLinkShimClient(const CConnection& aConnection, CNifManSubConnectionShim& aSubConnectionShim) : |
|
31 iConnection(aConnection), |
|
32 iSubConnectionShim(aSubConnectionShim), |
|
33 iOutstandingProgressNotification(EFalse), |
|
34 iOutstandingDataSentNotification(EFalse), |
|
35 iOutstandingDataReceivedNotification(EFalse), |
|
36 iOutstandingSubConnectionActivity(EFalse) |
|
37 /** |
|
38 */ |
|
39 { |
|
40 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tCSubConnectionLinkShimClient() created for id %d, iConnection %08x"), |
|
41 this, aSubConnectionShim.Id(), &iConnection)); |
|
42 } |
|
43 |
|
44 CSubConnectionLinkShimClient::~CSubConnectionLinkShimClient() |
|
45 /** |
|
46 Complete all outstanding RMessages |
|
47 |
|
48 */ |
|
49 { |
|
50 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\t~CSubConnectionLinkShimClient(), id %d, iSubConnectionShim %08x"), |
|
51 this, iSubConnectionShim.Id(), this, &iSubConnectionShim)); |
|
52 |
|
53 if(iActivityTimer) |
|
54 { |
|
55 iActivityTimer->Cancel(); |
|
56 delete iActivityTimer; |
|
57 iActivityTimer = NULL; |
|
58 } |
|
59 |
|
60 if(iOutstandingProgressNotification) |
|
61 iOutstandingProgressNotificationMessage.Complete(KErrCancel); |
|
62 if(iOutstandingDataSentNotification) |
|
63 iOutstandingDataSentNotificationMessage.Complete(KErrCancel); |
|
64 if(iOutstandingDataReceivedNotification) |
|
65 iOutstandingDataReceivedNotificationMessage.Complete(KErrCancel); |
|
66 if(iOutstandingSubConnectionActivity) |
|
67 iOutstandingSubConnectionActivityMessage.Complete(KErrCancel); |
|
68 if (iSubConnectionShim.DataTransferShim()) |
|
69 { |
|
70 iSubConnectionShim.DataTransferShim()->DeRegisterClient(*this); |
|
71 } |
|
72 } |
|
73 |
|
74 TBool CSubConnectionLinkShimClient::Match(const CConnection& aConnection) const |
|
75 { |
|
76 return &iConnection == &aConnection; |
|
77 } |
|
78 |
|
79 TSubConnectionUniqueId CSubConnectionLinkShimClient::Id() |
|
80 { |
|
81 return iSubConnectionShim.Id(); |
|
82 } |
|
83 |
|
84 TInt CSubConnectionLinkShimClient::ReturnCode() const |
|
85 { |
|
86 return iReturnCode; |
|
87 } |
|
88 |
|
89 TInt CSubConnectionLinkShimClient::GetCurrentProgress(TNifProgress& aProgress) |
|
90 /** |
|
91 Return the current progress state |
|
92 |
|
93 @param aProgress On return, contains the current progress from the subconnection |
|
94 @return KErrNone if successful; otherwise one of the system-wide error codes |
|
95 */ |
|
96 { |
|
97 aProgress = iCurrentProgress; |
|
98 |
|
99 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tGetCurrentProgress() => (%d, %d)"), |
|
100 this, aProgress.iStage, aProgress.iError)); |
|
101 return KErrNone; |
|
102 } |
|
103 |
|
104 TBool CSubConnectionLinkShimClient::StopL(const RMessage2& aMessage) |
|
105 { |
|
106 TInt stopCode = 0; |
|
107 RConnection::TConnStopType stopType = static_cast<RConnection::TConnStopType>(aMessage.Int1()); |
|
108 switch (stopType) |
|
109 { |
|
110 case RConnection::EStopNormal: |
|
111 stopCode = KErrCancel; |
|
112 break; |
|
113 case RConnection::EStopAuthoritative: |
|
114 stopCode = KErrConnectionTerminated; |
|
115 break; |
|
116 default: |
|
117 stopCode = KErrCancel; // to remove compile warning |
|
118 User::Leave(KErrArgument); |
|
119 } |
|
120 |
|
121 TInt ret = iSubConnectionShim.Provider().Stop(iSubConnectionShim.Id(), stopCode, &aMessage); |
|
122 if (ret != KErrNone) |
|
123 { |
|
124 User::Leave(ret); |
|
125 } |
|
126 return ETrue; |
|
127 } |
|
128 |
|
129 TBool CSubConnectionLinkShimClient::DataTransferredL(const RMessage2& aMessage) |
|
130 { |
|
131 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataTransferredL(), id %d"), |
|
132 this, iSubConnectionShim.Id())); |
|
133 |
|
134 TUint uplinkDataVolume; |
|
135 TUint downlinkDataVolume; |
|
136 |
|
137 TInt ret = iSubConnectionShim.DataTransferShim()->DataTransferred(uplinkDataVolume, downlinkDataVolume); |
|
138 |
|
139 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataTransferredL(), ret %d, uplink %d, downlink %d"), |
|
140 this, ret, uplinkDataVolume, downlinkDataVolume)); |
|
141 |
|
142 if (KErrNone == ret) |
|
143 { |
|
144 TPckg<TUint> uplinkDataVolumePckg(uplinkDataVolume); |
|
145 TPckg<TUint> downlinkDataVolumePckg(downlinkDataVolume); |
|
146 |
|
147 aMessage.WriteL(1, uplinkDataVolumePckg); |
|
148 aMessage.WriteL(2, downlinkDataVolumePckg); |
|
149 } |
|
150 SetReturnCode(ret); |
|
151 return ETrue; |
|
152 } |
|
153 |
|
154 TBool CSubConnectionLinkShimClient::DataTransferredCancel(const RMessage2& /*aMessage*/) |
|
155 { |
|
156 return ETrue; |
|
157 } |
|
158 |
|
159 TBool CSubConnectionLinkShimClient::RequestSubConnectionProgressNotificationL(const RMessage2& aMessage) |
|
160 /** |
|
161 Request from client for notification of new progress |
|
162 |
|
163 @pre No outstanding request for data sent notifications for this subconnection on this RConnection |
|
164 @param aMessage The client message |
|
165 @return ETrue if the client message is to be completed immediately |
|
166 @leave leaves with KErrInUse if there is already an outstanding RMessage for progress notification |
|
167 */ |
|
168 { |
|
169 if(iOutstandingProgressNotification) |
|
170 User::Leave(KErrInUse); |
|
171 |
|
172 TInt clientRequestedProgress = 0; |
|
173 clientRequestedProgress = static_cast<TUint>(aMessage.Int2()); |
|
174 // if - the last progress we sent to the client differs from the current one |
|
175 // and - the current progress is the same as the client requested progress OR |
|
176 // the client has no requested progress... |
|
177 if(iLastProgressToClient!=iCurrentProgress.iStage && |
|
178 (iCurrentProgress.iStage == clientRequestedProgress || clientRequestedProgress==0)) |
|
179 { |
|
180 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tRequestSubConnectionProgressNotificationL() returning progress (%d, %d)"), |
|
181 this, iCurrentProgress.iStage, iCurrentProgress.iError)); |
|
182 |
|
183 // ...send the current progress back |
|
184 TPckg<TNifProgress> prog(iCurrentProgress); |
|
185 aMessage.WriteL(1, prog); |
|
186 return ETrue; |
|
187 } |
|
188 else // store the client message until the next progress value arrives |
|
189 { |
|
190 //__FLOG_STATIC1(_L("ESock: "), _L("CSubConnectionLinkShimClient"), |
|
191 // _L("[id: %d]: client requested progress notification; storing client message for later completion"), |
|
192 // iSubConnectionsUniqueId); |
|
193 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tRequestSubConnectionProgressNotificationL() storing client message for later completion"), this)); |
|
194 |
|
195 iClientRequestedProgress = clientRequestedProgress; // may be 0 |
|
196 iOutstandingProgressNotificationMessage = aMessage; |
|
197 iOutstandingProgressNotification = ETrue; |
|
198 return EFalse; |
|
199 } |
|
200 } |
|
201 |
|
202 TBool CSubConnectionLinkShimClient::CancelSubConnectionProgressNotification(const RMessage2& /*aMessage*/) |
|
203 /** |
|
204 Complete outstanding progress notification RMessage |
|
205 |
|
206 @param aMessage The client message |
|
207 @return ETrue if the client message is to be completed immediately |
|
208 */ |
|
209 { |
|
210 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tCancelSubConnectionProgressNotification(), id %d, iSubConnectionShim %08x"), |
|
211 iSubConnectionShim.Id(), this)); |
|
212 |
|
213 if(iOutstandingProgressNotification) |
|
214 { |
|
215 iOutstandingProgressNotificationMessage.Complete(KErrCancel); |
|
216 iOutstandingProgressNotification = EFalse; |
|
217 } |
|
218 return ETrue; |
|
219 } |
|
220 |
|
221 TBool CSubConnectionLinkShimClient::DataSentNotificationRequestL(const RMessage2& aMessage) |
|
222 /** |
|
223 Request notification when the specified (absolute or relative) volume of data has been sent |
|
224 |
|
225 @pre No outstanding request for data sent notifications for this subconnection on this RConnection |
|
226 @param aMessage The client message |
|
227 @return ETrue if the client message is to be completed immeadiately |
|
228 @leave leaves with KErrInUse if there is already an outstanding RMessage for data sent notification |
|
229 */ |
|
230 { |
|
231 if(iOutstandingDataSentNotification) |
|
232 User::Leave(KErrInUse); |
|
233 |
|
234 TUint requestedUplinkGranularity = static_cast<TUint>(aMessage.Int1()); |
|
235 if(requestedUplinkGranularity) // the client is working in relative mode |
|
236 { |
|
237 iRemainingUplinkGranularity = requestedUplinkGranularity; |
|
238 iDataSentNotificationsInAbsoluteMode = EFalse; |
|
239 |
|
240 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataSentNotificationRequestL(), id %d (relative mode: %d bytes)"), |
|
241 this, iSubConnectionShim.Id(), iRemainingUplinkGranularity)); |
|
242 } |
|
243 else // the client is working in absolute mode |
|
244 { |
|
245 TPckg<TUint> iUplinkVolumeBuf(iUplinkDataNotificationVolume); |
|
246 aMessage.ReadL(2, iUplinkVolumeBuf); |
|
247 iDataSentNotificationsInAbsoluteMode = ETrue; |
|
248 |
|
249 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataSentNotificationRequestL() id %d (absolute mode: %d bytes)"), |
|
250 this, iSubConnectionShim.Id(), iUplinkDataNotificationVolume)); |
|
251 |
|
252 if(iUplinkDataNotificationVolume >= iUplinkDataVolume) // we've already sent this amount of data |
|
253 { |
|
254 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataSentNotificationRequestL() id %d (completed immediately"), |
|
255 this, iSubConnectionShim.Id())); |
|
256 return ETrue; |
|
257 } |
|
258 } |
|
259 |
|
260 iOutstandingDataSentNotificationMessage = aMessage; |
|
261 iOutstandingDataSentNotification = ETrue; |
|
262 |
|
263 iSubConnectionShim.DataTransferShim()->DataSentNotificationRequest(requestedUplinkGranularity, iUplinkDataNotificationVolume); |
|
264 |
|
265 return EFalse; |
|
266 } |
|
267 |
|
268 TBool CSubConnectionLinkShimClient::DataSentNotificationCancel(const RMessage2& /*aMessage*/) |
|
269 /** |
|
270 Complete outstanding data sent notification RMessage |
|
271 |
|
272 @param aMessage The client message |
|
273 @return ETrue if the client message is to be completed immediately |
|
274 */ |
|
275 { |
|
276 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataSentNotificationCancel() id %d"), |
|
277 this, iSubConnectionShim.Id())); |
|
278 iSubConnectionShim.DataTransferShim()->DataSentNotificationCancel(); |
|
279 |
|
280 if(iOutstandingDataSentNotification) |
|
281 { |
|
282 iOutstandingDataSentNotificationMessage.Complete(KErrCancel); |
|
283 iOutstandingDataSentNotification= EFalse; |
|
284 } |
|
285 return ETrue; |
|
286 } |
|
287 |
|
288 TBool CSubConnectionLinkShimClient::DataReceivedNotificationRequestL(const RMessage2& aMessage) |
|
289 /** |
|
290 Request notification when the specified (absolute or relative) volume of data has been sent |
|
291 |
|
292 @pre No outstanding request for data sent notifications for this subconnection on this RConnection |
|
293 @param aMessage The client message |
|
294 @return ETrue if the client message is to be completed immediately |
|
295 @leave leaves with KErrInUse if there is already an outstanding RMessage for data received notification |
|
296 */ |
|
297 { |
|
298 |
|
299 if(iOutstandingDataReceivedNotification) |
|
300 User::Leave(KErrInUse); |
|
301 |
|
302 TUint requestedDownlinkGranularity = static_cast<TUint>(aMessage.Int1()); |
|
303 if(requestedDownlinkGranularity) // the client is working in relative mode |
|
304 { |
|
305 iRemainingDownlinkGranularity = requestedDownlinkGranularity; |
|
306 iDataReceivedNotificationsInAbsoluteMode = EFalse; |
|
307 |
|
308 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataReceivedNotificationRequestL() id %d (relative mode: %d bytes)"), |
|
309 this, iSubConnectionShim.Id(), iRemainingDownlinkGranularity)); |
|
310 } |
|
311 else // the client is working in absolute mode |
|
312 { |
|
313 TPckg<TUint> iDownlinkVolumeBuf(iDownlinkDataNotificationVolume); |
|
314 aMessage.ReadL(2, iDownlinkVolumeBuf); |
|
315 iDataReceivedNotificationsInAbsoluteMode = ETrue; |
|
316 |
|
317 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataReceivedNotificationRequestL() id %d (absolute mode: %d bytes)"), |
|
318 this, iSubConnectionShim.Id(), iDownlinkDataNotificationVolume)); |
|
319 |
|
320 if(iDownlinkDataNotificationVolume >= iDownlinkDataVolume) // we've already received this amount of data |
|
321 { |
|
322 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataReceivedNotificationRequestL() id %d(completed immediately)"), |
|
323 this, iSubConnectionShim.Id())); |
|
324 return ETrue; |
|
325 } |
|
326 } |
|
327 |
|
328 iOutstandingDataReceivedNotificationMessage = aMessage; |
|
329 iOutstandingDataReceivedNotification = ETrue; |
|
330 |
|
331 iSubConnectionShim.DataTransferShim()->DataReceivedNotificationRequest(requestedDownlinkGranularity, iDownlinkDataNotificationVolume); |
|
332 |
|
333 return EFalse; |
|
334 } |
|
335 |
|
336 TBool CSubConnectionLinkShimClient::DataReceivedNotificationCancel(const RMessage2& /*aMessage*/) |
|
337 /** |
|
338 Complete outstanding data received notification RMessage |
|
339 |
|
340 @param aMessage The client message |
|
341 @return ETrue if the client message is to be completed immediately |
|
342 */ |
|
343 { |
|
344 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tDataReceivedNotificationCancel() id %d"), |
|
345 this, iSubConnectionShim.Id())); |
|
346 |
|
347 iSubConnectionShim.DataTransferShim()->DataReceivedNotificationCancel(); |
|
348 |
|
349 if(iOutstandingDataReceivedNotification) |
|
350 { |
|
351 iOutstandingDataReceivedNotificationMessage.Complete(KErrCancel); |
|
352 iOutstandingDataReceivedNotification = EFalse; |
|
353 } |
|
354 return ETrue; |
|
355 } |
|
356 |
|
357 TBool CSubConnectionLinkShimClient::IsSubConnectionActiveRequestL(const RMessage2& aMessage) |
|
358 /** |
|
359 Indicate whether the subconnection is active or not |
|
360 |
|
361 @note Checks at a period defined in the RMessage |
|
362 @note Only returns when the state varies from that provided by the client |
|
363 @param aMessage The client message |
|
364 @return ETrue if the client message is to be completed immediately |
|
365 */ |
|
366 { |
|
367 if(iOutstandingSubConnectionActivity) |
|
368 User::Leave(KErrInUse); |
|
369 |
|
370 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tIsSubConnectionActiveRequestL() id %d"), |
|
371 this, iSubConnectionShim.Id())); |
|
372 |
|
373 // Create the activity timer if it doesn't already exist (from a previous request) |
|
374 if(!iActivityTimer) |
|
375 { |
|
376 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tIsSubConnectionActiveRequestL() id %d - creating timer"), |
|
377 this, iSubConnectionShim.Id())); |
|
378 |
|
379 iActivityTimer = CActivityTimer::NewL(this, KActivityTimerPriority); |
|
380 } |
|
381 |
|
382 TPckg<TBool> subConnectionActiveBuf(iClientBelievesSubConnectionActive); |
|
383 aMessage.ReadL(2, subConnectionActiveBuf); |
|
384 |
|
385 iSubConnectionShim.DataTransferShim()->DataTransferred(iPreviousUplinkDataVolume, iPreviousDownlinkDataVolume); |
|
386 |
|
387 // get clients request timer period and check validity |
|
388 TInt timeInSeconds = static_cast<TUint>(aMessage.Int1()); |
|
389 if(timeInSeconds > KMaxTimerPeriod) // secs; underlying CTimer limitation |
|
390 { |
|
391 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tIsSubConnectionActiveRequestL() id %d - rejecting timer request (%d secs)"), |
|
392 this, iSubConnectionShim.Id(), timeInSeconds)); |
|
393 |
|
394 SetReturnCode(KErrArgument); |
|
395 return ETrue; |
|
396 } |
|
397 |
|
398 // store in microsecs |
|
399 iRequestedClientTimerPeriod = timeInSeconds * KMicrosecondsInASecond; |
|
400 |
|
401 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tIsSubConnectionActiveRequestL() id %d, iClientBelievesSubConnectionActive %d, iRequestedClientTimerPeriod %d - Starting timer."), |
|
402 this, iSubConnectionShim.Id(), iClientBelievesSubConnectionActive, iRequestedClientTimerPeriod)); |
|
403 |
|
404 iOutstandingSubConnectionActivity = ETrue; |
|
405 iOutstandingSubConnectionActivityMessage = aMessage; |
|
406 |
|
407 iActivityTimer->After(iRequestedClientTimerPeriod); |
|
408 return EFalse; |
|
409 } |
|
410 |
|
411 TBool CSubConnectionLinkShimClient::IsSubConnectionActiveCancel(const RMessage2& /*aMessage*/) |
|
412 { |
|
413 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tIsSubConnectionActiveCancel() id %d, connection %08x"), |
|
414 this, iSubConnectionShim.Id(), &iConnection)); |
|
415 |
|
416 if(iOutstandingSubConnectionActivity) |
|
417 { |
|
418 iActivityTimer->Cancel(); |
|
419 ASSERT(iOutstandingSubConnectionActivity); // assert that the timer cancelled rather than completing |
|
420 iOutstandingSubConnectionActivityMessage.Complete(KErrCancel); |
|
421 iOutstandingSubConnectionActivity = EFalse; |
|
422 } |
|
423 return ETrue; |
|
424 } |
|
425 |
|
426 TInt CSubConnectionLinkShimClient::GetSubConnectionInfo(const RMessage2& aMessage) |
|
427 { |
|
428 TUint index = static_cast<TUint>(aMessage.Int0()); |
|
429 |
|
430 TInt result = KErrNone; |
|
431 TRAP(result, |
|
432 |
|
433 // Find the size of the clients descriptor |
|
434 TInt sizeOfSubConnInfo = aMessage.GetDesLengthL(1); |
|
435 |
|
436 // Create an appropriately sized descriptor server-side |
|
437 HBufC8* subConnectionInfo; |
|
438 subConnectionInfo = HBufC8::NewL(sizeOfSubConnInfo); |
|
439 CleanupStack::PushL (subConnectionInfo); |
|
440 |
|
441 TPtr8 subConnInfoPtr(subConnectionInfo->Des()); |
|
442 |
|
443 // and read the client data across |
|
444 aMessage.ReadL(1, subConnInfoPtr); |
|
445 |
|
446 // Pass it down to the connection provider using the appropriate call |
|
447 if(index==KUseEmbeddedUniqueId) |
|
448 { |
|
449 result = iSubConnectionShim.Provider().GetSubConnectionInfo(subConnInfoPtr); |
|
450 } |
|
451 else |
|
452 { |
|
453 result = iSubConnectionShim.Provider().GetSubConnectionInfo(index, subConnInfoPtr); |
|
454 } |
|
455 |
|
456 if (KErrNone == result) |
|
457 { |
|
458 // Write result back into client's address space |
|
459 aMessage.WriteL(1, subConnInfoPtr); |
|
460 } |
|
461 |
|
462 CleanupStack::PopAndDestroy (subConnectionInfo); |
|
463 ); // END TRAP |
|
464 |
|
465 SetReturnCode(result); |
|
466 return ETrue; |
|
467 } |
|
468 |
|
469 void CSubConnectionLinkShimClient::ProgressNotification(TInt aStage, TInt aError, const TDesC8& /*aInfo*/) |
|
470 /** |
|
471 Notification of new progress stage from nif/agent via Nifman and CInterface |
|
472 |
|
473 @param aStage The progress stage that has been reached |
|
474 @param aError Any errors that have occured |
|
475 @param aInfo No idea what this is, it's inserted by CInterface and is currently null |
|
476 */ |
|
477 { |
|
478 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tProgressNotification(%d, %d) id %d"), |
|
479 this, aStage, aError, iSubConnectionShim.Id())); |
|
480 |
|
481 iCurrentProgress.iStage = aStage; |
|
482 iCurrentProgress.iError = aError; |
|
483 |
|
484 if(iOutstandingProgressNotification) |
|
485 { |
|
486 if(iLastProgressToClient!=iCurrentProgress.iStage && /* we could assume this since we've probably just received a new progress value */ |
|
487 (iCurrentProgress.iStage == iClientRequestedProgress || iClientRequestedProgress==0)) |
|
488 { |
|
489 TPckg<TNifProgress> prog(iCurrentProgress); |
|
490 TInt err= iOutstandingProgressNotificationMessage.Write(1, prog); |
|
491 iOutstandingProgressNotificationMessage.Complete(err); |
|
492 iOutstandingProgressNotification= EFalse; |
|
493 } |
|
494 } |
|
495 } |
|
496 |
|
497 TInt CSubConnectionLinkShimClient::NotifyDataSent(TUint aUplinkVolume, TUint aCurrentGranularity) |
|
498 /** |
|
499 Upcall from connection provider, via MConnDataTransferNotify. Update the sent bytes count, and if necessary |
|
500 complete any outstanding RMessages |
|
501 |
|
502 @param aUplinkVolume The total number of bytes sent on this subconnection |
|
503 @note Upcall from CInterface via CConnection |
|
504 */ |
|
505 { |
|
506 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tNotifyDataSent(aUplinkVolume %d, aCurrentGranularity %d) id %d"), |
|
507 this, aUplinkVolume, aCurrentGranularity, iSubConnectionShim.Id())); |
|
508 |
|
509 iUplinkDataVolume = aUplinkVolume; |
|
510 |
|
511 TBool completeMessage = EFalse; |
|
512 |
|
513 if(iOutstandingDataSentNotification) |
|
514 { |
|
515 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - outstanding client request"), |
|
516 this, iSubConnectionShim.Id())); |
|
517 switch(iDataSentNotificationsInAbsoluteMode) |
|
518 { |
|
519 case ETrue: |
|
520 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - %d bytes remaining to be sent before client completion (absolute mode)"), |
|
521 this, iSubConnectionShim.Id(), (iUplinkDataNotificationVolume - iUplinkDataVolume))); |
|
522 |
|
523 if (iUplinkDataVolume >= iUplinkDataNotificationVolume) |
|
524 { |
|
525 completeMessage = ETrue; |
|
526 } |
|
527 break; |
|
528 |
|
529 case EFalse: // in relative mode |
|
530 iRemainingUplinkGranularity -= aCurrentGranularity; |
|
531 |
|
532 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - %d bytes remaining to be sent before client completion (relative mode)."), |
|
533 this, iSubConnectionShim.Id(), iRemainingUplinkGranularity)); |
|
534 |
|
535 if(iRemainingUplinkGranularity <= 0) |
|
536 { |
|
537 completeMessage = ETrue; |
|
538 } |
|
539 break; |
|
540 |
|
541 default: |
|
542 break; |
|
543 } |
|
544 } |
|
545 |
|
546 if(completeMessage) |
|
547 { |
|
548 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - completing client request."), |
|
549 iSubConnectionShim.Id(), this)); |
|
550 TPckg<TUint> iUplinkDataVolumePckg(iUplinkDataVolume); |
|
551 TInt ret= iOutstandingDataSentNotificationMessage.Write(2, iUplinkDataVolumePckg); |
|
552 iOutstandingDataSentNotificationMessage.Complete(ret); |
|
553 iOutstandingDataSentNotification= EFalse; |
|
554 } |
|
555 return KErrNone; |
|
556 } |
|
557 |
|
558 TInt CSubConnectionLinkShimClient::NotifyDataReceived(TUint aDownlinkVolume, TUint aCurrentGranularity) |
|
559 /** |
|
560 Update the received bytes count, and if necessary complete any outstanding RMessages |
|
561 |
|
562 @param aDownlinkVolume The total number of bytes sent on this subconnection |
|
563 @param aCurrentGranularity The currently set granularity of notifications from the CInterface object |
|
564 @note Upcall from CInterface via CConnection |
|
565 */ |
|
566 { |
|
567 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tNotifyDataReceived(aDownlinkVolume %d, aCurrentGranularity %d)"), |
|
568 this, iSubConnectionShim.Id(), aDownlinkVolume, aCurrentGranularity)); |
|
569 |
|
570 iDownlinkDataVolume = aDownlinkVolume; |
|
571 |
|
572 TBool completeMessage = EFalse; |
|
573 |
|
574 if(iOutstandingDataReceivedNotification) |
|
575 { |
|
576 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - outstanding client request"), |
|
577 this, iSubConnectionShim.Id())); |
|
578 switch(iDataReceivedNotificationsInAbsoluteMode) |
|
579 { |
|
580 case ETrue: |
|
581 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - %d bytes remaining to be sent before client completion (absolute mode)."), |
|
582 this, iSubConnectionShim.Id(), (iDownlinkDataNotificationVolume - iDownlinkDataVolume))); |
|
583 |
|
584 if (iDownlinkDataVolume >= iDownlinkDataNotificationVolume) |
|
585 { |
|
586 completeMessage = ETrue; |
|
587 } |
|
588 break; |
|
589 |
|
590 case EFalse: // in relative mode |
|
591 iRemainingDownlinkGranularity -= aCurrentGranularity; |
|
592 |
|
593 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - %d bytes remaining to be sent before client completion (relative mode)."), |
|
594 this, iSubConnectionShim.Id(), iRemainingDownlinkGranularity)); |
|
595 |
|
596 if(iRemainingDownlinkGranularity <= 0) |
|
597 { |
|
598 completeMessage = ETrue; |
|
599 } |
|
600 break; |
|
601 |
|
602 default: |
|
603 break; |
|
604 } |
|
605 } |
|
606 |
|
607 if(completeMessage) |
|
608 { |
|
609 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - completing client request."), |
|
610 this, &iSubConnectionShim)); |
|
611 TPckg<TUint> iDownlinkDataVolumePckg(iDownlinkDataVolume); |
|
612 TInt ret= iOutstandingDataReceivedNotificationMessage.Write(2, iDownlinkDataVolumePckg); |
|
613 iOutstandingDataReceivedNotificationMessage.Complete(ret); |
|
614 iOutstandingDataReceivedNotification= EFalse; |
|
615 } |
|
616 return KErrNone; |
|
617 } |
|
618 |
|
619 TInt CSubConnectionLinkShimClient::NotifyDataTransferred(const TUint aUplinkVolume, const TUint aDownlinkVolume) |
|
620 /** |
|
621 Upcall from CConnection, indicating that it has performed a DataTransferred request and notifying us of the results |
|
622 |
|
623 @param aUplinkVolume The total amount of data sent so far on this subconnection |
|
624 @param aDownlinkVolume The total amount of data received so far on this subconnection |
|
625 */ |
|
626 { |
|
627 // Update internal data counters, complete any outstanding RMessages if appropriate |
|
628 // No granularities because we don't know what they are, and because we're taking the |
|
629 // opportunity of using the client's call to update our counters, ie. it's not an |
|
630 // actual notification |
|
631 NotifyDataSent(aUplinkVolume, 0); |
|
632 NotifyDataReceived(aDownlinkVolume, 0); |
|
633 return KErrNone; |
|
634 } |
|
635 |
|
636 void CSubConnectionLinkShimClient::CheckSubConnectionActivity() |
|
637 /** |
|
638 Check for activity on the subconnection since the last call (to IsSubConnectionActiveRequest() ) |
|
639 |
|
640 */ |
|
641 { |
|
642 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tCheckSubConnectionActivity() id %d"), |
|
643 this, iSubConnectionShim.Id())); |
|
644 |
|
645 ASSERT(iOutstandingSubConnectionActivity); |
|
646 |
|
647 TUint newUplinkDataVolume; |
|
648 TUint newDownlinkDataVolume; |
|
649 |
|
650 iSubConnectionShim.DataTransferShim()->DataTransferred(newUplinkDataVolume, newDownlinkDataVolume); |
|
651 |
|
652 TBool dataTransferred = (newUplinkDataVolume!=iPreviousUplinkDataVolume) || |
|
653 (newDownlinkDataVolume!=iPreviousDownlinkDataVolume); |
|
654 |
|
655 // If the data transferred volumes haven't change but the client thinks the connection is active... |
|
656 if(iClientBelievesSubConnectionActive) |
|
657 { |
|
658 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - client believes subconnection active"), |
|
659 this, iSubConnectionShim.Id())); |
|
660 |
|
661 if(dataTransferred) // ...and it is, so just start another timer cycle |
|
662 { |
|
663 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - ...and it is. Restart timer for another cycle."), |
|
664 this, iSubConnectionShim.Id())); |
|
665 |
|
666 iPreviousUplinkDataVolume = newUplinkDataVolume; |
|
667 iPreviousDownlinkDataVolume = newDownlinkDataVolume; |
|
668 iActivityTimer->After(iRequestedClientTimerPeriod); |
|
669 } |
|
670 else // ...tell them it's not |
|
671 { |
|
672 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - ...and it isn't. Notify client."), |
|
673 this, iSubConnectionShim.Id())); |
|
674 |
|
675 TPckg<TBool> subConnectionActiveBuf(dataTransferred); |
|
676 TInt ret= iOutstandingSubConnectionActivityMessage.Write(2, subConnectionActiveBuf); |
|
677 iOutstandingSubConnectionActivityMessage.Complete(ret); |
|
678 iOutstandingSubConnectionActivity = EFalse; |
|
679 } |
|
680 } |
|
681 else // client believes subconnection is idle... |
|
682 { |
|
683 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - client believes subconnection idle..."), |
|
684 this, iSubConnectionShim.Id())); |
|
685 |
|
686 if(dataTransferred) |
|
687 { |
|
688 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - ...and it isn't. Notify client."), |
|
689 this, iSubConnectionShim.Id())); |
|
690 |
|
691 TPckg<TBool> subConnectionActiveBuf(dataTransferred); |
|
692 TInt ret= iOutstandingSubConnectionActivityMessage.Write(2, subConnectionActiveBuf); |
|
693 iOutstandingSubConnectionActivityMessage.Complete(ret); |
|
694 iOutstandingSubConnectionActivity = EFalse; |
|
695 } |
|
696 else // ...and it is, so just start another timer cycle |
|
697 { |
|
698 __CFLOG_VAR((KShimScprTag, KShimScprClientTag, _L8("CSubConnectionLinkShimClient %08x:\tid %d - ...and it is. Restart timer for another cycle."), |
|
699 this, iSubConnectionShim.Id())); |
|
700 |
|
701 iPreviousUplinkDataVolume = newUplinkDataVolume; |
|
702 iPreviousDownlinkDataVolume = newDownlinkDataVolume; |
|
703 iActivityTimer->After(iRequestedClientTimerPeriod); |
|
704 } |
|
705 } |
|
706 } |
|
707 |
|
708 CSubConnectionLinkShimClient::CActivityTimer* CSubConnectionLinkShimClient::CActivityTimer::NewL(CSubConnectionLinkShimClient* aOwner, TInt aPriority) |
|
709 /** |
|
710 Construct a new CActivityTimer() |
|
711 |
|
712 @param aOwner The owning CSubConnectionLinkShimClient (on which we call methods upon timer completion) |
|
713 @param aPriority The priority of the active object underlying this timer object |
|
714 @return A pointer to the newly constructed CActivityTimer object |
|
715 */ |
|
716 { |
|
717 CSubConnectionLinkShimClient::CActivityTimer* newActivityTimer = |
|
718 new(ELeave) CSubConnectionLinkShimClient::CActivityTimer(aOwner, aPriority); |
|
719 |
|
720 CleanupStack::PushL(newActivityTimer); |
|
721 newActivityTimer->ConstructL(); |
|
722 CleanupStack::Pop(newActivityTimer); |
|
723 return newActivityTimer; |
|
724 } |
|
725 |
|
726 void CSubConnectionLinkShimClient::CActivityTimer::RunL() |
|
727 /** |
|
728 Call the owning object's check activity method |
|
729 |
|
730 */ |
|
731 { |
|
732 iOwner->CheckSubConnectionActivity(); |
|
733 } |