1 /* |
|
2 * Copyright (c) 2005-2007 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: Monitors the VOIP calls. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32property.h> |
|
20 #include <telephonydomainpskeys.h> |
|
21 |
|
22 // Call Information API |
|
23 #include <ccallinformation.h> |
|
24 |
|
25 // SP Settings |
|
26 #include <spdefinitions.h> |
|
27 #include <spentry.h> |
|
28 #include <spproperty.h> |
|
29 #include <spsettings.h> |
|
30 |
|
31 #include "musvoipcallmonitor.h" |
|
32 #include "mussesseioninformationapi.h" |
|
33 #include "muslogger.h" |
|
34 |
|
35 const TUint KMusAoRemoteInfoMonitoringTimeout = 2000000; // 2 seconds |
|
36 _LIT( KSipAt, "@" ); |
|
37 |
|
38 // ----------------------------------------------------------------------------- |
|
39 // Symbian two-phase constructor. |
|
40 // ----------------------------------------------------------------------------- |
|
41 // |
|
42 CMusVoipCallMonitor* CMusVoipCallMonitor::NewL( TName& aCallName, |
|
43 MMusCallStateObserver& aCallStateObserver ) |
|
44 { |
|
45 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::NewL" ) |
|
46 CMusVoipCallMonitor* self = |
|
47 new (ELeave) CMusVoipCallMonitor( aCallName, aCallStateObserver ); |
|
48 CleanupStack::PushL( self ); |
|
49 self->ConstructL( ); |
|
50 CleanupStack::Pop( self ); |
|
51 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::NewL" ) |
|
52 return self; |
|
53 } |
|
54 |
|
55 |
|
56 // ----------------------------------------------------------------------------- |
|
57 // C++ destructor. |
|
58 // ----------------------------------------------------------------------------- |
|
59 // |
|
60 CMusVoipCallMonitor::~CMusVoipCallMonitor() |
|
61 { |
|
62 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::~CMusVoipCallMonitor" ) |
|
63 |
|
64 ResetCallProviderName(); |
|
65 |
|
66 StopRemoteInfoMonitoring(); |
|
67 |
|
68 iPropertyEvent.Close(); |
|
69 |
|
70 delete iGuardTimer; |
|
71 |
|
72 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::~CMusVoipCallMonitor" ) |
|
73 } |
|
74 |
|
75 |
|
76 // ----------------------------------------------------------------------------- |
|
77 // C++ constructor. |
|
78 // ----------------------------------------------------------------------------- |
|
79 // |
|
80 CMusVoipCallMonitor::CMusVoipCallMonitor( TName& aCallName, |
|
81 MMusCallStateObserver& aCallStateObserver ): |
|
82 CActive( CActive::EPriorityStandard ), |
|
83 iCallName ( aCallName ), |
|
84 iCallStateObserver ( aCallStateObserver ), |
|
85 iGuardTimerCallBack( GuardTimerExpired, this ) |
|
86 { |
|
87 CActiveScheduler::Add( this ); |
|
88 |
|
89 iGuardTimerEntry.Set( iGuardTimerCallBack ); |
|
90 } |
|
91 |
|
92 |
|
93 // ----------------------------------------------------------------------------- |
|
94 // Symbian second-phase constructor. |
|
95 // ----------------------------------------------------------------------------- |
|
96 // |
|
97 void CMusVoipCallMonitor::ConstructL( ) |
|
98 { |
|
99 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::ConstructL" ) |
|
100 |
|
101 User::LeaveIfError( iPropertyEvent.Attach( |
|
102 KPSUidTelRemotePartyInformation, |
|
103 KTelCLINumber ) ); |
|
104 |
|
105 iGuardTimer = CDeltaTimer::NewL( CActive::EPriorityStandard ); |
|
106 |
|
107 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::ConstructL" ) |
|
108 } |
|
109 |
|
110 // ----------------------------------------------------------------------------- |
|
111 // CMusVoipCallMonitor::SetStateL( ) |
|
112 // Sets the call state property key.See mussesseioninformationapi.h |
|
113 // Also sets the call information if call state is Connected. |
|
114 // If call is connected but remote info cannot be found, information |
|
115 // publishing is delayed until remote info comes available or monitoring |
|
116 // for the info timeouts. In voip case, remote info should be basically |
|
117 // always available, but in some cases it is not immediately available |
|
118 // when call status changes to connected. |
|
119 // ----------------------------------------------------------------------------- |
|
120 // |
|
121 void CMusVoipCallMonitor::SetStateL(NMusSessionInformationApi::TMusCallEvent aVal) |
|
122 { |
|
123 MUS_LOG1( "mus: [MUSAO] -> CMusVoipCallMonitor::SetStateL, aVal %d", aVal ) |
|
124 // set the call state only if the call count is one else it should be decided |
|
125 // by conference monitor or line/tsy monitor. |
|
126 |
|
127 TBool delayStateChange( EFalse ); |
|
128 if ( aVal == NMusSessionInformationApi::ECallConnected ) |
|
129 { |
|
130 if ( !RemoteInfoExistsL() ) |
|
131 { |
|
132 MonitorForRemoteInfoL(); |
|
133 delayStateChange = ETrue; |
|
134 } |
|
135 } |
|
136 else |
|
137 { |
|
138 StopRemoteInfoMonitoring(); |
|
139 } |
|
140 |
|
141 if ( delayStateChange ) |
|
142 { |
|
143 MUS_LOG( "mus: [MUSAO] state change delayed!" ) |
|
144 } |
|
145 else |
|
146 { |
|
147 ReportStateChangeL( aVal ); |
|
148 } |
|
149 |
|
150 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::SetStateL" ) |
|
151 } |
|
152 |
|
153 ///----------------------------------------------------------------------------- |
|
154 // CMusVoipCallMonitor::SetCallInfoL( ) |
|
155 // ----------------------------------------------------------------------------- |
|
156 // |
|
157 void CMusVoipCallMonitor::SetCallInfoL() |
|
158 { |
|
159 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::SetCallInfoL") |
|
160 |
|
161 // Set Call Provider Information |
|
162 TUint32 serviceId = CallServiceIdL(); |
|
163 SetCallProviderInfoL( serviceId ); |
|
164 |
|
165 HBufC* remoteUri = HBufC::NewLC( RProperty::KMaxPropertySize ); |
|
166 TPtr rUri = remoteUri->Des(); |
|
167 TInt err = RProperty::Get( KPSUidTelRemotePartyInformation, |
|
168 KTelCLINumber, |
|
169 rUri ); |
|
170 |
|
171 if ( err == KErrNone && remoteUri->Des().Length() > 0 ) |
|
172 { |
|
173 MUS_LOG_TDESC( "mus: [MUSAO] voip remote name: ", remoteUri->Des()); |
|
174 |
|
175 // Add "sip:" prefix to remoteUri unless it already exists |
|
176 _LIT( KSipPrefix, "sip:" ); |
|
177 TPtr prefix = remoteUri->Des().LeftTPtr( KSipPrefix().Length() ); |
|
178 if ( prefix.Compare( KSipPrefix ) != 0 ) |
|
179 { |
|
180 if ( remoteUri->Des().Length() + KSipPrefix().Length() > |
|
181 remoteUri->Des().MaxLength() ) |
|
182 { |
|
183 User::Leave( KErrOverflow ); |
|
184 } |
|
185 remoteUri->Des().Insert( 0, KSipPrefix ); |
|
186 } |
|
187 //if domain not present, add domain from voip profile (username) |
|
188 if ( remoteUri->Find( KSipAt ) == KErrNotFound ) |
|
189 { |
|
190 rUri.Set( remoteUri->Des() ); |
|
191 AddDomainFromOwnUsernameL( serviceId, rUri ); |
|
192 MUS_LOG_TDESC ( "mus: [MUSAO] full voip remote name:", (*remoteUri) ) |
|
193 } |
|
194 } |
|
195 else |
|
196 { |
|
197 remoteUri->Des().Zero(); |
|
198 } |
|
199 |
|
200 User::LeaveIfError( RProperty::Set( |
|
201 NMusSessionInformationApi::KCategoryUid, |
|
202 NMusSessionInformationApi::KMusTelNumber, remoteUri->Des() ) ); |
|
203 |
|
204 CleanupStack::PopAndDestroy(remoteUri); |
|
205 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::SetCallInfoL" ) |
|
206 } |
|
207 |
|
208 ///----------------------------------------------------------------------------- |
|
209 // CMusVoipCallMonitor::AddDomainFromOwnUsernameL( ) |
|
210 // ----------------------------------------------------------------------------- |
|
211 // |
|
212 void CMusVoipCallMonitor::AddDomainFromOwnUsernameL( |
|
213 TUint32 /*aServiceId*/, |
|
214 TDes16& /*aUri*/ ) |
|
215 { |
|
216 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::AddDomainFromOwnUsernameL") |
|
217 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::AddDomainFromOwnUsernameL, NOT SUPPORTED") |
|
218 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::AddDomainFromOwnUsernameL") |
|
219 } |
|
220 |
|
221 ///----------------------------------------------------------------------------- |
|
222 // CMusVoipCallMonitor::CallServiceIdL( ) |
|
223 // ----------------------------------------------------------------------------- |
|
224 // |
|
225 TUint32 CMusVoipCallMonitor::CallServiceIdL() |
|
226 { |
|
227 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::CallServiceIdL") |
|
228 TUint32 serviceId( 0 ); |
|
229 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::CallServiceIdL, NOT SUPPORTED") |
|
230 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::CallServiceIdL") |
|
231 return serviceId; |
|
232 } |
|
233 |
|
234 ///----------------------------------------------------------------------------- |
|
235 // CMusVoipCallMonitor::SetCallProviderInfoL( ) |
|
236 // ----------------------------------------------------------------------------- |
|
237 // |
|
238 void CMusVoipCallMonitor::SetCallProviderInfoL( TUint32 aServiceId ) |
|
239 { |
|
240 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::SetCallProviderInfoL") |
|
241 CSPSettings* settings = CSPSettings::NewLC(); |
|
242 CSPEntry* entry = CSPEntry::NewLC(); |
|
243 |
|
244 TInt errorCode = settings->FindEntryL( aServiceId, *entry ); |
|
245 |
|
246 if ( errorCode == KErrNone && entry != NULL ) |
|
247 { |
|
248 const TDesC& name = entry->GetServiceName(); |
|
249 |
|
250 MUS_LOG_TDESC ( "mus: [MUSAO]] CallProviderName IS -->", name ) |
|
251 User::LeaveIfError(RProperty::Set( |
|
252 NMusSessionInformationApi::KCategoryUid, |
|
253 NMusSessionInformationApi::KMUSCallProvider, |
|
254 name)); |
|
255 } |
|
256 |
|
257 CleanupStack::PopAndDestroy( entry ); |
|
258 CleanupStack::PopAndDestroy( settings ); |
|
259 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::SetCallProviderInfoL" ) |
|
260 } |
|
261 |
|
262 |
|
263 // ----------------------------------------------------------------------------- |
|
264 // Checks the aName is equal to this monitors name. |
|
265 // @return ETrue if matches else EFalse |
|
266 // ----------------------------------------------------------------------------- |
|
267 // |
|
268 TBool CMusVoipCallMonitor::IsEqual(TName& aName) |
|
269 { |
|
270 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::IsEqual" ) |
|
271 MUS_LOG_TDESC( "mus: [MUSAO] -> aName : ", aName ); |
|
272 MUS_LOG_TDESC( "mus: [MUSAO] -> iCallName : ", iCallName ); |
|
273 TBool val = EFalse ; |
|
274 val = ( aName == iCallName ); |
|
275 MUS_LOG1( "mus: [MUSAO] <- CMusCallMonitor::IsEqual = %d",val ) |
|
276 return val; |
|
277 } |
|
278 |
|
279 // ----------------------------------------------------------------------------- |
|
280 // CMusVoipCallMonitor::RunL |
|
281 // ----------------------------------------------------------------------------- |
|
282 // |
|
283 void CMusVoipCallMonitor::RunL() |
|
284 { |
|
285 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::RunL" ) |
|
286 |
|
287 if ( RemoteInfoExistsL() ) |
|
288 { |
|
289 // Connected state reporting was delayed because not having |
|
290 // remote info, now it can be reported and monitoring is not needed anymore |
|
291 StopRemoteInfoMonitoring(); |
|
292 ReportStateChangeL( NMusSessionInformationApi::ECallConnected ); |
|
293 } |
|
294 else |
|
295 { |
|
296 // resubscribe |
|
297 iPropertyEvent.Subscribe( iStatus ); |
|
298 SetActive(); |
|
299 } |
|
300 |
|
301 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::RunL" ) |
|
302 } |
|
303 |
|
304 |
|
305 // ----------------------------------------------------------------------------- |
|
306 // CMusVoipCallMonitor::DoCancel |
|
307 // ----------------------------------------------------------------------------- |
|
308 // |
|
309 void CMusVoipCallMonitor::DoCancel() |
|
310 { |
|
311 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::DoCancel" ) |
|
312 |
|
313 iPropertyEvent.Cancel(); |
|
314 |
|
315 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::DoCancel" ) |
|
316 } |
|
317 |
|
318 // ----------------------------------------------------------------------------- |
|
319 // CMusVoipCallMonitor::RunError |
|
320 // ----------------------------------------------------------------------------- |
|
321 // |
|
322 TInt CMusVoipCallMonitor::RunError( TInt aError ) |
|
323 { |
|
324 MUS_LOG1( "mus: [MUSAO] -> CMusVoipCallMonitor::RunError = %d", aError ) |
|
325 if ( aError != KErrNoMemory ) |
|
326 { |
|
327 aError = KErrNone; |
|
328 } |
|
329 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::RunError" ) |
|
330 return aError; |
|
331 } |
|
332 |
|
333 // ----------------------------------------------------------------------------- |
|
334 // CMusVoipCallMonitor::RemoteInfoExistsL |
|
335 // ----------------------------------------------------------------------------- |
|
336 // |
|
337 TBool CMusVoipCallMonitor::RemoteInfoExistsL() |
|
338 { |
|
339 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::RemoteInfoExistsL" ) |
|
340 |
|
341 HBufC* remoteUri = HBufC::NewLC(RProperty::KMaxPropertySize); |
|
342 TPtr rUri = remoteUri->Des(); |
|
343 |
|
344 TInt err = RProperty::Get( KPSUidTelRemotePartyInformation, |
|
345 KTelCLINumber, |
|
346 rUri ); |
|
347 |
|
348 TBool remoteInfoExists( err == KErrNone && remoteUri->Des().Length() > 0 ); |
|
349 CleanupStack::PopAndDestroy(remoteUri); |
|
350 |
|
351 MUS_LOG1( "mus: [MUSAO] <- CMusVoipCallMonitor::RemoteInfoExistsL = %d", |
|
352 remoteInfoExists ) |
|
353 |
|
354 return remoteInfoExists; |
|
355 } |
|
356 |
|
357 // ----------------------------------------------------------------------------- |
|
358 // CMusVoipCallMonitor::MonitorForRemoteInfoL |
|
359 // Start monitoring remote info P&S key. Guard timer is started |
|
360 // to prevent waiting for the infomation forever. |
|
361 // ----------------------------------------------------------------------------- |
|
362 // |
|
363 void CMusVoipCallMonitor::MonitorForRemoteInfoL() |
|
364 { |
|
365 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::MonitorForRemoteInfoL" ) |
|
366 |
|
367 if ( !IsActive() ) |
|
368 { |
|
369 MUS_LOG( "mus: [MUSAO] activate" ) |
|
370 |
|
371 iGuardTimer->Remove( iGuardTimerEntry ); |
|
372 TTimeIntervalMicroSeconds32 interval( KMusAoRemoteInfoMonitoringTimeout ); |
|
373 iGuardTimer->Queue( interval, iGuardTimerEntry ); |
|
374 |
|
375 iPropertyEvent.Subscribe( iStatus ); |
|
376 SetActive(); |
|
377 } |
|
378 |
|
379 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::MonitorForRemoteInfoL" ) |
|
380 } |
|
381 |
|
382 // ----------------------------------------------------------------------------- |
|
383 // CMusVoipCallMonitor::MonitorForRemoteInfoL |
|
384 // ----------------------------------------------------------------------------- |
|
385 // |
|
386 void CMusVoipCallMonitor::StopRemoteInfoMonitoring() |
|
387 { |
|
388 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::StopRemoteInfoMonitoring" ) |
|
389 |
|
390 if ( iGuardTimer ) |
|
391 { |
|
392 iGuardTimer->Remove( iGuardTimerEntry ); |
|
393 } |
|
394 |
|
395 Cancel(); |
|
396 |
|
397 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::StopRemoteInfoMonitoring" ) |
|
398 } |
|
399 |
|
400 // ----------------------------------------------------------------------------- |
|
401 // CMusVoipCallMonitor::ReportStateChangeL |
|
402 // ----------------------------------------------------------------------------- |
|
403 // |
|
404 void CMusVoipCallMonitor::ReportStateChangeL( |
|
405 NMusSessionInformationApi::TMusCallEvent aVal ) |
|
406 { |
|
407 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::ReportStateChangeL" ) |
|
408 |
|
409 TInt currentVal = 0; |
|
410 User::LeaveIfError(RProperty::Get( NMusSessionInformationApi::KCategoryUid, |
|
411 NMusSessionInformationApi::KMusCallEvent, |
|
412 currentVal)); |
|
413 |
|
414 |
|
415 // Report only if the value changed else do not publish. |
|
416 if(currentVal != (TInt)aVal) |
|
417 { |
|
418 User::LeaveIfError(RProperty::Set( |
|
419 NMusSessionInformationApi::KCategoryUid, |
|
420 NMusSessionInformationApi::KMusCallEvent, |
|
421 aVal )); |
|
422 } |
|
423 // When call is connected and the callcount is one, |
|
424 // set the call informations. |
|
425 if( aVal==NMusSessionInformationApi::ECallConnected ) |
|
426 { |
|
427 SetCallInfoL(); |
|
428 } |
|
429 |
|
430 iCallStateObserver.MusCallStateChanged(); |
|
431 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::ReportStateChangeL" ) |
|
432 } |
|
433 |
|
434 // ----------------------------------------------------------------------------- |
|
435 // CMusVoipCallMonitor::GuardTimerExpired |
|
436 // If timer expired, it took too long to get remote party information via |
|
437 // P&S monitoring. Because of monitoring, call connected was not yet informed, |
|
438 // inform it now. |
|
439 // ----------------------------------------------------------------------------- |
|
440 // |
|
441 TInt CMusVoipCallMonitor::GuardTimerExpired( TAny* aPtr ) |
|
442 { |
|
443 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::GuardTimerExpired" ) |
|
444 if ( aPtr ) |
|
445 { |
|
446 CMusVoipCallMonitor* self = reinterpret_cast<CMusVoipCallMonitor*>( aPtr ); |
|
447 self->StopRemoteInfoMonitoring(); |
|
448 TRAP_IGNORE( |
|
449 self->ReportStateChangeL( NMusSessionInformationApi::ECallConnected ) ) |
|
450 } |
|
451 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::GuardTimerExpired" ) |
|
452 |
|
453 return KErrNone; |
|
454 } |
|
455 |
|
456 // -------------------------------------------------------------------------------- |
|
457 // CMusCallConferenceMonitor::IsDataReadyL() |
|
458 // Checks if Data is ready VoIP Call. |
|
459 // -------------------------------------------------------------------------------- |
|
460 |
|
461 TBool CMusVoipCallMonitor::IsDataReadyL() |
|
462 { |
|
463 //This function need to updated if some other P/S Key is published |
|
464 //to ensure correct behaviour. |
|
465 |
|
466 MUS_LOG( "mus: [MUSAO] -> CMusVoipCallMonitor::IsDataReadyL" ) |
|
467 |
|
468 // Ensure Provider Information is Availble. |
|
469 HBufC* providerInfo = HBufC::NewLC( RProperty::KMaxPropertySize ); |
|
470 TPtr pInfo = providerInfo->Des(); |
|
471 TInt err = KErrNone; |
|
472 |
|
473 err = RProperty::Get( NMusSessionInformationApi::KCategoryUid, |
|
474 NMusSessionInformationApi::KMUSCallProvider, |
|
475 pInfo ); |
|
476 |
|
477 TBool providerInfoExisit ( err == KErrNone && providerInfo->Des().Length() > 0 ); |
|
478 CleanupStack::PopAndDestroy( providerInfo ); |
|
479 |
|
480 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::IsDataReadyL" ) |
|
481 return !IsActive() && providerInfoExisit; |
|
482 } |
|
483 |
|
484 |
|
485 // -------------------------------------------------------------------------------- |
|
486 // Reset the Call Provider Information. |
|
487 // -------------------------------------------------------------------------------- |
|
488 |
|
489 void CMusVoipCallMonitor::ResetCallProviderName( ) |
|
490 { |
|
491 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::ResetCallProviderName" ) |
|
492 TInt errorCode = RProperty::Set( NMusSessionInformationApi::KCategoryUid, |
|
493 NMusSessionInformationApi::KMUSCallProvider, |
|
494 KNullDesC ); |
|
495 |
|
496 // Error Code is just for debug only |
|
497 MUS_LOG1( "mus: [MUSAO] ErrorCode = %d", errorCode ) |
|
498 MUS_LOG( "mus: [MUSAO] <- CMusVoipCallMonitor::ResetCallProviderName" ) |
|
499 } |
|
500 |
|
501 |
|
502 // End of file |
|