|
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: Provide interface for the client requestin availability class. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "musavaoptionhandler.h" |
|
20 |
|
21 #include <escapeutils.h> |
|
22 #include <siperr.h> |
|
23 #include "musunittesting.h" |
|
24 #include "musavasharedobject.h" |
|
25 #include "muslogger.h" |
|
26 #include "musavasip.h" |
|
27 #include "musavasettingsimp.h" |
|
28 #include "musavacapabilitysipagent.h" |
|
29 #include "musavacapabilityexchange.h" |
|
30 #include "musavacapabilityquery.h" |
|
31 #include "musavacapability.h" |
|
32 #include "musavacapabilityquerybase.h" |
|
33 #include "musavaterminal.h" |
|
34 #include "mussettingskeys.h" |
|
35 #include "mussettings.h" |
|
36 |
|
37 |
|
38 _LIT( KMusSipPrefix, "sip:" ); |
|
39 _LIT( KMusTelPrefix, "tel:" ); |
|
40 _LIT( KMusPlusSign, "+" ); |
|
41 |
|
42 const TInt KMaxUriLength = 512; |
|
43 const TInt KMusMinDigitCountInTelNumber = 7; |
|
44 |
|
45 const TInt KMusOptionsHandlerIndex = 1; |
|
46 |
|
47 |
|
48 // ----------------------------------------------------------------------------- |
|
49 // |
|
50 // ----------------------------------------------------------------------------- |
|
51 // |
|
52 CMusAvaOptionHandler* CMusAvaOptionHandler::NewL( |
|
53 MMusAvaAvailabilityObserver& aObserver, |
|
54 CMusAvaSettingsImp& aSettings ) |
|
55 { |
|
56 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewL()" ) |
|
57 CMusAvaOptionHandler* self = CMusAvaOptionHandler::NewLC( |
|
58 aObserver, |
|
59 aSettings ); |
|
60 CleanupStack::Pop( self ); |
|
61 |
|
62 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewL()" ) |
|
63 return self; |
|
64 } |
|
65 |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 CMusAvaOptionHandler* CMusAvaOptionHandler::NewLC( |
|
72 MMusAvaAvailabilityObserver& aObserver, |
|
73 CMusAvaSettingsImp& aSettings ) |
|
74 { |
|
75 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewLC()" ) |
|
76 CMusAvaOptionHandler* self = new( ELeave ) CMusAvaOptionHandler( |
|
77 aObserver, |
|
78 aSettings ); |
|
79 CleanupStack::PushL( self ); |
|
80 self->ConstructL(); |
|
81 |
|
82 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::NewLC()" ) |
|
83 return self; |
|
84 } |
|
85 |
|
86 |
|
87 // ----------------------------------------------------------------------------- |
|
88 // |
|
89 // ----------------------------------------------------------------------------- |
|
90 // |
|
91 CMusAvaOptionHandler::~CMusAvaOptionHandler() |
|
92 { |
|
93 MUS_LOG( |
|
94 "mus: [MUSAVA] -> CMusAvaOptionHandler::~CMusAvaOptionHandler()" ) |
|
95 if (iSharedObj ) |
|
96 { |
|
97 iSharedObj->DeleteSingleton(); |
|
98 } |
|
99 delete iCapabilityExchange; |
|
100 iCapabilityExchange = NULL; |
|
101 delete iSipAgent; |
|
102 iSipAgent = NULL; |
|
103 |
|
104 MUS_LOG( |
|
105 "mus: [MUSAVA] <- CMusAvaOptionHandler::~CMusAvaOptionHandler()" ) |
|
106 } |
|
107 |
|
108 |
|
109 // ----------------------------------------------------------------------------- |
|
110 // |
|
111 // ----------------------------------------------------------------------------- |
|
112 // |
|
113 CMusAvaOptionHandler::CMusAvaOptionHandler( |
|
114 MMusAvaAvailabilityObserver& aObserver, |
|
115 CMusAvaSettingsImp& aSettings ) |
|
116 :CMusAvaAvailability( aObserver ), |
|
117 iSettings( aSettings ) |
|
118 { |
|
119 } |
|
120 |
|
121 |
|
122 // ----------------------------------------------------------------------------- |
|
123 // |
|
124 // ----------------------------------------------------------------------------- |
|
125 // |
|
126 void CMusAvaOptionHandler::ConstructL() |
|
127 { |
|
128 MUS_LOG( "mus: [MUSAVA] -> CMusAvaOptionHandler::ConstructL()" ) |
|
129 |
|
130 //construct capability exchange |
|
131 ConstructCapabilityExchangeL(); |
|
132 |
|
133 iSharedObj = CMusAvaSharedObject::GetSingletonL(); |
|
134 iSipAgent = CMusAvaCapabilitySipAgent::NewL( *iCapabilityExchange, |
|
135 *iSharedObj, |
|
136 iObserver ); |
|
137 iSharedObj->MusAvaSip().AddAdapterL( |
|
138 ( MMusAvaSipConnectionAdapter& ) *iSipAgent, |
|
139 KMusOptionsHandlerIndex ); |
|
140 iSharedObj->MusAvaSip().AddAdapterL( |
|
141 ( MMusAvaSipAdapter& ) *iSipAgent, |
|
142 KMusOptionsHandlerIndex ); |
|
143 |
|
144 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::ConstructL()" ) |
|
145 } |
|
146 |
|
147 |
|
148 // ----------------------------------------------------------------------------- |
|
149 // |
|
150 // ----------------------------------------------------------------------------- |
|
151 // |
|
152 TBool CMusAvaOptionHandler::CapabilityQueryAnswered( TBool aAnswered ) |
|
153 { |
|
154 iCapabilityQueryAnswered = aAnswered ? aAnswered : iCapabilityQueryAnswered; |
|
155 |
|
156 return iCapabilityQueryAnswered; |
|
157 |
|
158 } |
|
159 |
|
160 // ----------------------------------------------------------------------------- |
|
161 // |
|
162 // ----------------------------------------------------------------------------- |
|
163 // |
|
164 void CMusAvaOptionHandler::ConstructCapabilityExchangeL() |
|
165 { |
|
166 MUS_LOG( |
|
167 "mus: [MUSAVA] -> CMusAvaOptionHandler::ConstructCapabilityExchangeL()" ) |
|
168 HBufC8* terminalId = ConstructTerminalIdL(); |
|
169 CleanupStack::PushL( terminalId ); |
|
170 |
|
171 //create capability exchange |
|
172 iCapabilityExchange = |
|
173 CMusAvaCapabilityExchange::NewL( *terminalId, *this ); |
|
174 |
|
175 //create SWIS capability |
|
176 CMusAvaCapability* capability = CMusAvaCapability::NewL( |
|
177 *iCapabilityExchange ); |
|
178 CleanupStack::PushL( capability ); |
|
179 iCapabilityExchange->AddCapabilityL( capability ); |
|
180 CleanupStack::Pop( capability ); |
|
181 |
|
182 iSwisCapability = capability; |
|
183 |
|
184 CleanupStack::PopAndDestroy( terminalId ); |
|
185 MUS_LOG( |
|
186 "mus: [MUSAVA] <- CMusAvaOptionHandler::ConstructCapabilityExchangeL()" ) |
|
187 } |
|
188 |
|
189 |
|
190 // ----------------------------------------------------------------------------- |
|
191 // @TODO: Currently terminal id is not in use i.e User-Agent header is not |
|
192 // sent in request nor response. |
|
193 // ----------------------------------------------------------------------------- |
|
194 // |
|
195 HBufC8* CMusAvaOptionHandler::ConstructTerminalIdL() |
|
196 { |
|
197 return KNullDesC8().AllocL(); |
|
198 } |
|
199 |
|
200 |
|
201 // ----------------------------------------------------------------------------- |
|
202 // Starts the loopy execution. |
|
203 // ----------------------------------------------------------------------------- |
|
204 // |
|
205 void CMusAvaOptionHandler::DoExecuteL() |
|
206 { |
|
207 MUS_LOG( "mus: [MUSAVA] -> CMusAvaOptionHandler::DoExecuteL()" ) |
|
208 |
|
209 MusSettingsKeys::TOperatorVariant variantSetting = |
|
210 MultimediaSharingSettings::OperatorVariantSettingL(); |
|
211 |
|
212 /* |
|
213 Do not resent the OPTIONS request in the below scenario |
|
214 i) Options Sent and waiting for Response. |
|
215 ii) We already sent OPTIONS and got positive response.So we know that |
|
216 other device is VS capable. |
|
217 iii) We already sent OPTIONS and got negative response.So we know that |
|
218 other device is VS incapable. |
|
219 |
|
220 Also OPTIONS should be sent only once if it matches to VS Call criteria. |
|
221 */ |
|
222 MUS_LOG1( "mus: [MUSAVA] - Current State %d",State() ) |
|
223 |
|
224 if ( State() == MMusAvaObserver::EMusAvaStatusOptionsSent || |
|
225 State() == MMusAvaObserver::EMusAvaStatusAvailable || |
|
226 State() == MMusAvaObserver::EMusAvaOptionNotAvailable ) |
|
227 { |
|
228 return; |
|
229 } |
|
230 |
|
231 if ( variantSetting == MusSettingsKeys::EOperatorSpecific |
|
232 && iSettings.CallDirection() == 2 && !iCapabilitiesRequestAnswered ) |
|
233 { // terminated party |
|
234 SetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); |
|
235 } |
|
236 else if ( MusSettingsKeys::ESequential == |
|
237 MultimediaSharingSettings::CapabilityQuerySettingL() |
|
238 && iSettings.CallDirection() == 2 && !iCapabilitiesRequestAnswered ) |
|
239 { // terminated party |
|
240 SetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); |
|
241 } |
|
242 else |
|
243 { |
|
244 if ( MusSettingsKeys::EOperatorSpecific == variantSetting || |
|
245 MusSettingsKeys::EParallel == |
|
246 MultimediaSharingSettings::CapabilityQuerySettingL() || |
|
247 MusSettingsKeys::ESequential == |
|
248 MultimediaSharingSettings::CapabilityQuerySettingL() ) |
|
249 { |
|
250 const MDesCArray& addresses = iSettings.SipAddresses(); |
|
251 |
|
252 TInt addressesCount = addresses.MdcaCount(); |
|
253 MUS_LOG1( "mus: [MUSAVA] addresses.MdcaCount() %d", |
|
254 addressesCount ) |
|
255 if( addressesCount ) |
|
256 { |
|
257 const TDesC& sipAddress = addresses.MdcaPoint( 0 ); |
|
258 MUS_LOG_TDESC( "mus: [MUSAVA] SIP Address: ", |
|
259 sipAddress ) |
|
260 TRAPD( err, iSipAgent->ExecuteCapabilityQueryL( |
|
261 *iSwisCapability, sipAddress ) ); |
|
262 // set status available and report to the observer |
|
263 if ( err == KErrNone ) |
|
264 { |
|
265 HBufC8* sipAddress8 = |
|
266 EscapeUtils::ConvertFromUnicodeToUtf8L( sipAddress ); |
|
267 CleanupStack::PushL( sipAddress8 ); |
|
268 if ( iCapabilityExchange-> |
|
269 TerminalL( sipAddress8->Des() ).QueryExecuting() ) |
|
270 { |
|
271 SetState( MMusAvaObserver::EMusAvaStatusOptionsSent ); |
|
272 } |
|
273 else |
|
274 { |
|
275 SetState( MMusAvaObserver::EMusAvaStatusAvailable ); |
|
276 } |
|
277 CleanupStack::PopAndDestroy( sipAddress8 ); |
|
278 } |
|
279 // when profile is in when needed mode and registration still on |
|
280 // going we get this error and wait untill registration is successful |
|
281 // since we did not send any options set the state EMusAvaStatusNotExecuted. |
|
282 else if( err == KErrSIPInvalidRegistrationState ) |
|
283 { |
|
284 SetState( MMusAvaObserver::EMusAvaStatusNotExecuted ); |
|
285 } |
|
286 // anything other than this should be considered default , means options sent |
|
287 // and was not successful. |
|
288 else |
|
289 { |
|
290 SetState( MMusAvaObserver::EMusAvaOptionNotAvailable ); |
|
291 } |
|
292 } |
|
293 else |
|
294 { |
|
295 SetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); |
|
296 } |
|
297 } |
|
298 else |
|
299 { |
|
300 // option sending not needed |
|
301 SetState( MMusAvaObserver::EMusAvaStatusOptionsNotSent ); |
|
302 } |
|
303 } |
|
304 |
|
305 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::DoExecuteL()" ) |
|
306 } |
|
307 |
|
308 |
|
309 // ----------------------------------------------------------------------------- |
|
310 // Stops executing availability. |
|
311 // ----------------------------------------------------------------------------- |
|
312 // |
|
313 void CMusAvaOptionHandler::Stop() |
|
314 { |
|
315 MUS_LOG( "mus: [MUSAVA] -> CMusAvaOptionHandler::Stop()" ) |
|
316 // TBD |
|
317 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::Stop()" ) |
|
318 } |
|
319 |
|
320 |
|
321 // ----------------------------------------------------------------------------- |
|
322 // Returns name of *this* availability. |
|
323 // ----------------------------------------------------------------------------- |
|
324 // |
|
325 MMusAvaObserver::TAvailabilityName CMusAvaOptionHandler::Name() |
|
326 { |
|
327 return MMusAvaObserver::EMusAvaOptionHandler; |
|
328 } |
|
329 |
|
330 |
|
331 // ----------------------------------------------------------------------------- |
|
332 // |
|
333 // ----------------------------------------------------------------------------- |
|
334 // |
|
335 void CMusAvaOptionHandler::CapabilitiesResolved( |
|
336 const CMusAvaCapabilityQueryBase& aSentQuery ) |
|
337 { |
|
338 MUS_LOG( |
|
339 "mus: [MUSAVA] -> CMusAvaOptionHandler::CapabilitiesResolved()" ) |
|
340 if ( aSentQuery.Result() == KCapabilityCapabilitesReady ) |
|
341 { |
|
342 // tell the upper layer that |
|
343 // query was succesfull. VS is available |
|
344 SetState( MMusAvaObserver::EMusAvaStatusAvailable ); |
|
345 } |
|
346 else if ( aSentQuery.Result() == KCapabilityCapabilitiesForbidden ) |
|
347 { |
|
348 // query returned with response "403 Forbidden". VS is NOT available |
|
349 SetState( MMusAvaObserver::EMusAvaFailureCode ); |
|
350 } |
|
351 else |
|
352 { |
|
353 //query failed. VS is NOT available |
|
354 SetState( MMusAvaObserver::EMusAvaOptionNotAvailable ); |
|
355 } |
|
356 |
|
357 MUS_LOG( |
|
358 "mus: [MUSAVA] <- CMusAvaOptionHandler::CapabilitiesResolved()" ) |
|
359 } |
|
360 |
|
361 |
|
362 // ----------------------------------------------------------------------------- |
|
363 // |
|
364 // ----------------------------------------------------------------------------- |
|
365 // |
|
366 void CMusAvaOptionHandler::CapabilitiesResolvedL( const TDesC& aUri ) |
|
367 { |
|
368 MUS_LOG( |
|
369 "mus: [MUSAVA] -> CMusAvaOptionHandler::CapabilitiesResolvedL()" ) |
|
370 if ( aUri.Length() > 0 ) |
|
371 { |
|
372 // Set the sip address resolved from succesfull OPTIONS response |
|
373 // Old adress(es) are destroyed |
|
374 CDesCArrayFlat* sipAddresses = new( ELeave ) CDesCArrayFlat( 1 ); |
|
375 CleanupStack::PushL( sipAddresses ); |
|
376 |
|
377 sipAddresses->AppendL( aUri ); |
|
378 iSettings.SetSipAddressesL( *sipAddresses ); |
|
379 |
|
380 MUS_LOG_TDESC( "mus: [MUSAVA] SIP Address: ", aUri ) |
|
381 |
|
382 sipAddresses->Reset(); |
|
383 CleanupStack::PopAndDestroy( sipAddresses ); |
|
384 } |
|
385 |
|
386 MUS_LOG( |
|
387 "mus: [MUSAVA] <- CMusAvaOptionHandler::CapabilitiesResolvedL()" ) |
|
388 } |
|
389 |
|
390 |
|
391 // ----------------------------------------------------------------------------- |
|
392 // |
|
393 // ----------------------------------------------------------------------------- |
|
394 // |
|
395 void CMusAvaOptionHandler::SetCapabilitiesResolvedForCingular() |
|
396 { |
|
397 MUS_LOG( |
|
398 "mus: [MUSAVA] -> CMusAvaOptionHandler::\ |
|
399 SetCapabilitiesResolvedForCingular()" ) |
|
400 iCapabilitiesRequestAnswered = ETrue; |
|
401 TRAPD( error, DoExecuteL() ); |
|
402 if ( error ) |
|
403 { |
|
404 MUS_LOG1( "mus: [MUSAVA] <- CMusAvaOptionHandler::\ |
|
405 SetCapabilitiesResolvedForCingular() leave code = %d", error ) |
|
406 } |
|
407 else |
|
408 { |
|
409 MUS_LOG( "mus: [MUSAVA] <- CMusAvaOptionHandler::\ |
|
410 SetCapabilitiesResolvedForCingular()" ) |
|
411 } |
|
412 } |
|
413 |
|
414 |
|
415 // ----------------------------------------------------------------------------- |
|
416 // |
|
417 // ----------------------------------------------------------------------------- |
|
418 // |
|
419 TBool CMusAvaOptionHandler::CapabilitiesResolvedForCingular() |
|
420 { |
|
421 MUS_LOG( |
|
422 "mus: [MUSAVA] CMusAvaOptionHandler::CapabilitiesResolvedForCingular()" ) |
|
423 return iCapabilitiesRequestAnswered; |
|
424 } |
|
425 |
|
426 |
|
427 // ----------------------------------------------------------------------------- |
|
428 // |
|
429 // ----------------------------------------------------------------------------- |
|
430 // |
|
431 void CMusAvaOptionHandler::SipHeadersL( |
|
432 const MDesCArray& aHeaders, |
|
433 SipStrConsts::TStrings aHeaderType) |
|
434 { |
|
435 MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::SipHeadersL()" ) |
|
436 |
|
437 // if header type is to then store in iSettings , so then future |
|
438 // request will be send there. |
|
439 if(aHeaderType == SipStrConsts::EToHeader) |
|
440 { |
|
441 // All addresses received should be valid, so choose just one to avoid |
|
442 // situation where user has to choose one from equal addresses. |
|
443 // Prefer SIP URI, but accept also TEL URI. |
|
444 |
|
445 TBuf<KMaxUriLength> sipUri; |
|
446 TBuf<KMaxUriLength> telUri; |
|
447 |
|
448 for ( TInt i = 0; i < aHeaders.MdcaCount(); ++i ) |
|
449 { |
|
450 if ( aHeaders.MdcaPoint( i ).FindF( KMusSipPrefix ) != |
|
451 KErrNotFound ) |
|
452 { |
|
453 sipUri.Copy( aHeaders.MdcaPoint( i ) ); |
|
454 } |
|
455 else if ( aHeaders.MdcaPoint(i).FindF( KMusTelPrefix ) != |
|
456 KErrNotFound ) |
|
457 { |
|
458 telUri.Copy( aHeaders.MdcaPoint( i ) ); |
|
459 } |
|
460 else |
|
461 { |
|
462 // NOP |
|
463 } |
|
464 } |
|
465 |
|
466 CDesCArray* addresses = new( ELeave ) CDesCArrayFlat( 1 ); |
|
467 CleanupStack::PushL( addresses ); |
|
468 |
|
469 if ( telUri.Length() > 0 ) |
|
470 { |
|
471 telUri.Trim(); |
|
472 addresses->AppendL( telUri ); |
|
473 // Check if TEL URI conforms to phone number currently hold. |
|
474 // If they do not match, we replace phone number with one parsed |
|
475 // out of received from P-Asserted-Identity header. Since in this |
|
476 // scenario we cannot be sure about validity of contact name either, |
|
477 // we empty the contact name. This is only not to show incorrect |
|
478 // information, but this solution does not show possibly existing |
|
479 // contact name. |
|
480 |
|
481 // We compare last seven digits, since that is the minimum amount |
|
482 // that can make up a valid telephone number. |
|
483 // Variable telUri holds also prefix, but that does not affect the |
|
484 // righthand comparison. |
|
485 |
|
486 MUS_LOG_TDESC( "mus: [MUSUI ] iSettings.TelNumber(): ", |
|
487 iSettings.TelNumber() ) |
|
488 MUS_LOG_TDESC( "mus: [MUSUI ] telUri: ", telUri ) |
|
489 |
|
490 TPtrC16 telUriWithoutPrefix = |
|
491 telUri.Right( telUri.Length() - KMusTelPrefix().Length() ); |
|
492 |
|
493 TPtrC16 numberPartOfTelUri = |
|
494 telUriWithoutPrefix.Find( KMusPlusSign ) == 0 ? |
|
495 telUriWithoutPrefix.Right( telUriWithoutPrefix.Length() - 1 ) : |
|
496 telUriWithoutPrefix; |
|
497 |
|
498 if ( !( iSettings.TelNumber().Length() >= KMusMinDigitCountInTelNumber && |
|
499 numberPartOfTelUri.Length() >= KMusMinDigitCountInTelNumber && |
|
500 iSettings.TelNumber().Right( KMusMinDigitCountInTelNumber ) == |
|
501 telUri.Right( KMusMinDigitCountInTelNumber ) ) ) |
|
502 { |
|
503 iSettings.SetTelNumberL( telUriWithoutPrefix ); |
|
504 iSettings.SetContactNameL( KNullDesC() ); |
|
505 iSettings.SetContactId( KErrNotFound ); |
|
506 } |
|
507 } |
|
508 |
|
509 if ( sipUri.Length() > 0 ) |
|
510 { |
|
511 // Replace possibly existing TEL URI with SIP URI |
|
512 addresses->Reset(); |
|
513 addresses->AppendL( sipUri ); |
|
514 } |
|
515 |
|
516 iSettings.SetSipAddressesL( addresses ); // Transfers ownership |
|
517 CleanupStack::Pop( addresses ); |
|
518 } |
|
519 else |
|
520 { |
|
521 // should go for future need if any. |
|
522 } |
|
523 MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::SipHeadersL()" ) |
|
524 } |
|
525 |
|
526 |
|
527 // ----------------------------------------------------------------------------- |
|
528 // |
|
529 // ----------------------------------------------------------------------------- |
|
530 // |
|
531 void CMusAvaOptionHandler::VideoCodecsResolvedL( const MDesCArray& aVideoCodecs ) |
|
532 { |
|
533 MUS_LOG("mus: [MUSAVA] -> CMusAvaOptionHandler::VideoCodecsResolvedL()" ) |
|
534 |
|
535 iSettings.SetVideoCodecsL(aVideoCodecs); |
|
536 |
|
537 MUS_LOG("mus: [MUSAVA] <- CMusAvaOptionHandler::VideoCodecsResolvedL()" ) |
|
538 } |
|
539 |