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: Capability (answer to OPTIONS) |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "musavacapability.h" |
|
21 #include "muslogger.h" |
|
22 #include "musavacapabilityexchange.h" |
|
23 #include "musavacapabilitycontext.h" |
|
24 #include "mmusavacapabilityqueryobserver.h" |
|
25 #include "mussettings.h" |
|
26 #include "mussettingskeys.h" |
|
27 |
|
28 #include <e32math.h> |
|
29 #include <uri8.h> |
|
30 #include <escapeutils.h> |
|
31 //#include <sip.h> |
|
32 #include <sipservertransaction.h> |
|
33 //#include <sipclienttransaction.h> |
|
34 #include <sipacceptcontactheader.h> |
|
35 #include <sipcontactheader.h> |
|
36 #include <siprequestelements.h> |
|
37 #include <sdpdocument.h> |
|
38 #include <sdpmediafield.h> |
|
39 #include <sdpconnectionfield.h> |
|
40 #include <sdporiginfield.h> |
|
41 #include <sdpfmtattributefield.h> |
|
42 #include <sdpattributefield.h> |
|
43 #include <sdprtpmapvalue.h> |
|
44 #include <sipstrings.h> |
|
45 #include <sdpcodecstringpool.h> |
|
46 #include <sipstrconsts.h> |
|
47 |
|
48 _LIT8(KSessionName, "-"); |
|
49 _LIT8(KOriginFieldUser, "-"); |
|
50 |
|
51 const TInt KMaxNumAsStringSize = 16; |
|
52 |
|
53 // -------------------------------------------------------------------------- |
|
54 // Symbian two-phase constructor |
|
55 // -------------------------------------------------------------------------- |
|
56 // |
|
57 CMusAvaCapability* CMusAvaCapability::NewL( |
|
58 CMusAvaCapabilityExchange& aExchange ) |
|
59 { |
|
60 MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapability::NewL" ) |
|
61 |
|
62 CMusAvaCapability* self = new (ELeave) CMusAvaCapability( aExchange ); |
|
63 CleanupStack::PushL( self ); |
|
64 self->ConstructL(); |
|
65 CleanupStack::Pop( self ); |
|
66 MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapability::NewL" ) |
|
67 |
|
68 return self; |
|
69 } |
|
70 |
|
71 // -------------------------------------------------------------------------- |
|
72 // C++ destructor |
|
73 // -------------------------------------------------------------------------- |
|
74 // |
|
75 CMusAvaCapability::~CMusAvaCapability() |
|
76 { |
|
77 MUS_LOG( |
|
78 "mus: [MUSAVA]: -> CMusAvaCapability::~CMusAvaCapability" ) |
|
79 |
|
80 iFeature.Close(); |
|
81 SIPStrings::Close(); |
|
82 SdpCodecStringPool::Close(); |
|
83 |
|
84 MUS_LOG( |
|
85 "mus: [MUSAVA]: <- CMusAvaCapability::~CMusAvaCapability" ) |
|
86 } |
|
87 |
|
88 |
|
89 // -------------------------------------------------------------------------- |
|
90 // C++ constructor |
|
91 // -------------------------------------------------------------------------- |
|
92 // |
|
93 CMusAvaCapability::CMusAvaCapability( |
|
94 CMusAvaCapabilityExchange& aExchange ) |
|
95 : iExchange( aExchange ), |
|
96 iIsEnabled( ETrue ) |
|
97 { |
|
98 } |
|
99 |
|
100 |
|
101 // -------------------------------------------------------------------------- |
|
102 // Symbian second-phase constructor |
|
103 // -------------------------------------------------------------------------- |
|
104 // |
|
105 void CMusAvaCapability::ConstructL( ) |
|
106 { |
|
107 MUS_LOG( "mus: [MUSAVA]: -> CMusAvaCapability::ConstructL" ) |
|
108 |
|
109 MUS_LOG( "mus: [MUSAVATEST]: SIPStrings::OpenL()" ) |
|
110 TRAP_IGNORE( SIPStrings::OpenL() ) |
|
111 TRAP_IGNORE( SdpCodecStringPool::OpenL() ) |
|
112 |
|
113 MUS_LOG( "mus: [MUSAVATEST]: MusAvaCapabilityContext::SIPStringL( KCapabilitySwisFeature )" ) |
|
114 iFeature = MusAvaCapabilityContext::SIPStringL( KCapabilitySwisFeature ); |
|
115 |
|
116 MUS_LOG( "mus: [MUSAVA]: <- CMusAvaCapability::ConstructL" ) |
|
117 } |
|
118 |
|
119 |
|
120 // -------------------------------------------------------------------------- |
|
121 // CMusAvaCapability::Exchange |
|
122 // -------------------------------------------------------------------------- |
|
123 // |
|
124 CMusAvaCapabilityExchange& CMusAvaCapability::Exchange() const |
|
125 { |
|
126 return iExchange; |
|
127 } |
|
128 |
|
129 |
|
130 // -------------------------------------------------------------------------- |
|
131 // CMusAvaCapability::Feature |
|
132 // -------------------------------------------------------------------------- |
|
133 // |
|
134 const RStringF& CMusAvaCapability::Feature() const |
|
135 { |
|
136 return iFeature; |
|
137 } |
|
138 |
|
139 |
|
140 // -------------------------------------------------------------------------- |
|
141 // CMusAvaCapability::Supports |
|
142 // -------------------------------------------------------------------------- |
|
143 // |
|
144 TBool CMusAvaCapability::Supports( |
|
145 const CSIPAcceptContactHeader& acceptContact ) |
|
146 { |
|
147 return acceptContact.HasParam( Feature() ); |
|
148 } |
|
149 |
|
150 |
|
151 // -------------------------------------------------------------------------- |
|
152 // CMusAvaCapability::Enabled |
|
153 // -------------------------------------------------------------------------- |
|
154 // |
|
155 TBool& CMusAvaCapability::Enabled() |
|
156 { |
|
157 return iIsEnabled; |
|
158 } |
|
159 |
|
160 |
|
161 // -------------------------------------------------------------------------- |
|
162 // CMusAvaCapability::PopulateResponseL |
|
163 // -------------------------------------------------------------------------- |
|
164 // |
|
165 void CMusAvaCapability::PopulateResponseL( |
|
166 CSIPServerTransaction& aQuery, |
|
167 RPointerArray<CSIPHeaderBase>& aResponseHeaders, |
|
168 CSdpDocument& aResponseContent ) |
|
169 |
|
170 { |
|
171 MUS_LOG( "mus: [MUSAVA]: -> CMusAvaCapability::PopulateResponseL" ) |
|
172 |
|
173 AddContactHeaderL( aQuery, aResponseHeaders ); |
|
174 |
|
175 DoPopulateResponseL( aResponseContent ); |
|
176 |
|
177 MUS_LOG( "mus: [MUSAVA]: <- CMusAvaCapability::PopulateResponseL" ) |
|
178 } |
|
179 |
|
180 // -------------------------------------------------------------------------- |
|
181 // CMusAvaCapability::DoPopulateResponseL |
|
182 // -------------------------------------------------------------------------- |
|
183 // |
|
184 void CMusAvaCapability::DoPopulateResponseL( CSdpDocument& aResponseContent ) |
|
185 |
|
186 { |
|
187 MUS_LOG( "mus: [MUSAVA] -> CMusAvaCapability::DoPopulateResponseL" ) |
|
188 |
|
189 MUS_LOG( "mus: [MUSAVA] Adding application attribute to SDP" ) |
|
190 //application |
|
191 CSdpAttributeField* application = CSdpAttributeField::NewLC( |
|
192 MusAvaCapabilityContext::SDPStringL( |
|
193 SdpCodecStringConstants::EMediaApplication ), |
|
194 KCapabilitySwisApplication ); |
|
195 |
|
196 aResponseContent.AttributeFields().AppendL( application ); |
|
197 CleanupStack::Pop( application ); |
|
198 |
|
199 MUS_LOG( "mus: [MUSAVA] Adding type attribute to SDP" ) |
|
200 //type |
|
201 RStringF typeStr = MusAvaCapabilityContext::SDPStringL( |
|
202 KCapabilitySDPAttributeNameType ); |
|
203 CleanupClosePushL( typeStr ); |
|
204 CSdpAttributeField* type = |
|
205 CSdpAttributeField::NewL( typeStr, KCapabilitySDPAttributeType ); |
|
206 CleanupStack::PopAndDestroy();//typeStr |
|
207 CleanupStack::PushL( type ); |
|
208 |
|
209 aResponseContent.AttributeFields().AppendL( type ); |
|
210 CleanupStack::Pop( type ); |
|
211 |
|
212 MUS_LOG( "mus: [MUSAVA] Adding media line to SDP" ) |
|
213 //media line |
|
214 CSdpMediaField* mediaLine = MediaLineLC( |
|
215 MusAvaCapabilityContext::SDPStringL( |
|
216 SdpCodecStringConstants::EMediaVideo ), |
|
217 KCapabilitySwisFormatListH263Only ); |
|
218 |
|
219 //adding H.264 codec to SDP |
|
220 if( !MultimediaSharingSettings::IsAvcDisabled()) |
|
221 { |
|
222 MUS_LOG( "mus: [MUSAVA] - Adding avc to supported codec list" ) |
|
223 // reconstruct media line with H264 and H263 |
|
224 CleanupStack::PopAndDestroy(mediaLine); |
|
225 mediaLine = MediaLineLC( |
|
226 MusAvaCapabilityContext::SDPStringL( |
|
227 SdpCodecStringConstants::EMediaVideo ), |
|
228 KCapabilitySwisFormatList ); |
|
229 |
|
230 //adding H.264 codec to SDP |
|
231 CSdpFmtAttributeField* rtpMapH264 = |
|
232 RtpMapLineLC( KCapabilitySDPAttributeCodecH264, |
|
233 KCapabilitySDPAttributePayloadTypeH264, |
|
234 KCapabilitySDPAttributeClockrate ); |
|
235 |
|
236 mediaLine->FormatAttributeFields().AppendL( rtpMapH264 ); |
|
237 CleanupStack::Pop( rtpMapH264 ); |
|
238 } |
|
239 //H.263 codec |
|
240 CSdpFmtAttributeField* rtpMapH263 = |
|
241 RtpMapLineLC( KCapabilitySDPAttributeCodecH263, |
|
242 KCapabilitySDPAttributePayloadType, |
|
243 KCapabilitySDPAttributeClockrate ); |
|
244 |
|
245 mediaLine->FormatAttributeFields().AppendL( rtpMapH263 ); |
|
246 CleanupStack::Pop( rtpMapH263 ); |
|
247 |
|
248 aResponseContent.MediaFields().AppendL( mediaLine ); |
|
249 CleanupStack::Pop( mediaLine ); |
|
250 |
|
251 |
|
252 MUS_LOG( "mus: [MUSAVA] <- CMusAvaCapability::DoPopulateResponseL" ) |
|
253 } |
|
254 |
|
255 |
|
256 // -------------------------------------------------------------------------- |
|
257 // CMusAvaCapability::ResponseContentLC |
|
258 // -------------------------------------------------------------------------- |
|
259 // |
|
260 CSdpDocument* CMusAvaCapability::ResponseContentLC( |
|
261 const CSIPServerTransaction& aQuery ) |
|
262 |
|
263 { |
|
264 MUS_LOG( |
|
265 "mus: [MUSAVA]: -> CMusAvaCapability::CreateResponseContentL" ) |
|
266 |
|
267 RStringF netType = |
|
268 MusAvaCapabilityContext::SDPStringL( SdpCodecStringConstants::ENetType ); |
|
269 |
|
270 CSdpDocument* responseContent = CSdpDocument::NewLC(); |
|
271 |
|
272 responseContent->SetSessionNameL( KSessionName ); |
|
273 |
|
274 TPtrC8 localHost; |
|
275 RStringF hostType; |
|
276 |
|
277 MusAvaCapabilityContext::LocalHostL( aQuery, localHost, hostType ); |
|
278 |
|
279 CSdpOriginField* originField = OriginFieldL( |
|
280 netType, localHost, hostType ); |
|
281 responseContent->SetOriginField( originField ); |
|
282 |
|
283 // Connection field |
|
284 CSdpConnectionField* connectionField = |
|
285 CSdpConnectionField::NewL( netType, hostType, localHost ); |
|
286 responseContent->SetConnectionField( connectionField ); |
|
287 |
|
288 MUS_LOG( |
|
289 "mus: [MUSAVA]: <- CMusAvaCapability::CreateResponseContentL" ) |
|
290 |
|
291 return responseContent; |
|
292 } |
|
293 |
|
294 |
|
295 // ----------------------------------------------------------------------------- |
|
296 // CMusAvaCapability::Codec |
|
297 // ----------------------------------------------------------------------------- |
|
298 // |
|
299 CDesCArrayFlat* CMusAvaCapability::ResolveCodecsL( CSdpDocument& aSDP ) |
|
300 { |
|
301 // TODO: use array of 2 elements, as we assume that max 2 codecs are supported (H.263 and H.264) |
|
302 CDesCArrayFlat* codecs = new( ELeave ) CDesCArrayFlat( 2 ); |
|
303 CleanupStack::PushL( codecs ); |
|
304 |
|
305 RStringF media = MusAvaCapabilityContext::SDPStringL( |
|
306 SdpCodecStringConstants::EMediaVideo ); |
|
307 |
|
308 RStringF rtpmap = MusAvaCapabilityContext::SDPStringL( |
|
309 SdpCodecStringConstants::EAttributeRtpmap ); |
|
310 |
|
311 RPointerArray<CSdpMediaField>& mediaFields = aSDP.MediaFields(); |
|
312 |
|
313 for ( TInt i=0; i < mediaFields.Count(); i++ ) |
|
314 { |
|
315 if ( mediaFields[ i ]->Media() == media ) |
|
316 { |
|
317 RPointerArray<CSdpFmtAttributeField>& fmtLines = |
|
318 mediaFields[ i ]->FormatAttributeFields(); |
|
319 |
|
320 for ( TInt j=0; j < fmtLines.Count(); j++ ) |
|
321 { |
|
322 if ( fmtLines[ j ]->Attribute() == rtpmap ) |
|
323 { |
|
324 if ( CAPABILITY_CONTAINS( fmtLines[ j ]->Value(), KCapabilitySDPAttributeCodecH263 ) |
|
325 || ( CAPABILITY_CONTAINS( fmtLines[ j ]->Value(), KCapabilitySDPAttributeCodecH264 ) && |
|
326 !MultimediaSharingSettings::IsAvcDisabled() ) ) |
|
327 { |
|
328 HBufC* codecBuf = |
|
329 EscapeUtils::ConvertToUnicodeFromUtf8L( fmtLines[ j ]->Value() ); |
|
330 CleanupStack::PushL( codecBuf ); |
|
331 codecs->AppendL( *codecBuf ); |
|
332 CleanupStack::PopAndDestroy( codecBuf ); |
|
333 } |
|
334 } |
|
335 } |
|
336 } |
|
337 } |
|
338 CleanupStack::Pop( codecs ); |
|
339 |
|
340 return codecs; |
|
341 } |
|
342 |
|
343 |
|
344 // ----------------------------------------------------------------------------- |
|
345 // CMusAvaCapability::Attribute |
|
346 // ----------------------------------------------------------------------------- |
|
347 // |
|
348 const CSdpAttributeField* CMusAvaCapability::Attribute( |
|
349 const RStringF& aAttribute, |
|
350 CSdpDocument& aSDP ) |
|
351 { |
|
352 const CSdpAttributeField* field = NULL; |
|
353 |
|
354 TBool found = EFalse; |
|
355 RPointerArray<CSdpAttributeField>& attributes = aSDP.AttributeFields(); |
|
356 |
|
357 for ( TInt i=0; i < attributes.Count() && !found; i++ ) |
|
358 { |
|
359 if ( attributes[ i ]->Attribute() == aAttribute ) |
|
360 { |
|
361 field = attributes[ i ]; |
|
362 found = ETrue; |
|
363 } |
|
364 } |
|
365 |
|
366 if ( !found ) |
|
367 { |
|
368 TRAP_IGNORE( field = Attribute( MusAvaCapabilityContext::SDPStringL( |
|
369 SdpCodecStringConstants::EMediaVideo ), |
|
370 aAttribute, |
|
371 aSDP ) ); |
|
372 } |
|
373 return field; |
|
374 } |
|
375 |
|
376 |
|
377 // ----------------------------------------------------------------------------- |
|
378 // CMusAvaCapability::Attribute |
|
379 // ----------------------------------------------------------------------------- |
|
380 // |
|
381 const CSdpAttributeField* CMusAvaCapability::Attribute( |
|
382 const RStringF& aMedia, |
|
383 const RStringF& aAttribute, |
|
384 CSdpDocument& aSDP ) |
|
385 { |
|
386 const CSdpAttributeField* field = NULL; |
|
387 |
|
388 TBool found = EFalse; |
|
389 RPointerArray<CSdpMediaField>& mediaFields = aSDP.MediaFields(); |
|
390 |
|
391 for ( TInt i=0; i < mediaFields.Count() && !found; i++ ) |
|
392 { |
|
393 if ( mediaFields[ i ]->Media() == aMedia ) |
|
394 { |
|
395 RPointerArray<CSdpAttributeField>& attributes = |
|
396 mediaFields[ i ]->AttributeFields(); |
|
397 |
|
398 for ( TInt j=0; j < attributes.Count() && !found; j++ ) |
|
399 { |
|
400 if ( attributes[ j ]->Attribute() == aAttribute ) |
|
401 { |
|
402 field = attributes[ j ]; |
|
403 found = ETrue; |
|
404 } |
|
405 } |
|
406 } |
|
407 } |
|
408 return field; |
|
409 } |
|
410 |
|
411 |
|
412 // -------------------------------------------------------------------------- |
|
413 // CMusAvaCapability::AddContactHeaderL |
|
414 // -------------------------------------------------------------------------- |
|
415 // |
|
416 void CMusAvaCapability::AddContactHeaderL( |
|
417 CSIPServerTransaction& aQuery, |
|
418 RPointerArray<CSIPHeaderBase>& aResponseHeaders ) |
|
419 { |
|
420 MUS_LOG( "mus: [MUSAVA]: -> CMusAvaCapability::AddContactHeaderL" ) |
|
421 |
|
422 const CUri8& uri = aQuery.RequestElements()->RemoteUri(); |
|
423 |
|
424 |
|
425 TBool cingular = |
|
426 MultimediaSharingSettings::OperatorVariantSettingL() == |
|
427 MusSettingsKeys::EOperatorSpecific; |
|
428 |
|
429 TBool alreadyRequested = iExchange.QueryObserver(). |
|
430 CapabilitiesResolvedForCingular() && cingular; |
|
431 |
|
432 CSIPContactHeader* contact = NULL; |
|
433 |
|
434 if ( alreadyRequested ) |
|
435 { |
|
436 contact = MusAvaCapabilityContext::ContactHeaderLC( uri, |
|
437 SIPStrings::StringF( SipStrConsts::EEmpty ) ); |
|
438 } |
|
439 else |
|
440 { |
|
441 //Contact header with feature tag |
|
442 contact = MusAvaCapabilityContext::ContactHeaderLC( uri, Feature() ); |
|
443 } |
|
444 |
|
445 aResponseHeaders.AppendL( contact ); |
|
446 CleanupStack::Pop( contact ); |
|
447 |
|
448 MUS_LOG( "mus: [MUSAVA]: <- CMusAvaCapability::AddContactHeaderL" ) |
|
449 } |
|
450 |
|
451 |
|
452 // ---------------------------------------------------------------------------- |
|
453 // CMusAvaCapability::OriginFieldL |
|
454 // ---------------------------------------------------------------------------- |
|
455 // |
|
456 CSdpOriginField* CMusAvaCapability::OriginFieldL( |
|
457 const RStringF& aNetType, |
|
458 const TDesC8& aLocalHost, |
|
459 const RStringF& aHostType ) |
|
460 { |
|
461 #ifdef CAPABILITY_UNIT_TESTING |
|
462 TInt64 sessionID = 452027953; |
|
463 #else |
|
464 TTime now; |
|
465 now.UniversalTime(); |
|
466 TInt64 rand = now.Int64(); |
|
467 TInt64 sessionID = Math::Rand( rand ); |
|
468 #endif |
|
469 |
|
470 return CSdpOriginField::NewL( KOriginFieldUser, |
|
471 sessionID, |
|
472 sessionID, |
|
473 aNetType, |
|
474 aHostType, |
|
475 aLocalHost ); |
|
476 } |
|
477 |
|
478 // ----------------------------------------------------------------------------- |
|
479 // CMusAvaCapability::MediaLineLC |
|
480 // ----------------------------------------------------------------------------- |
|
481 // |
|
482 CSdpMediaField* CMusAvaCapability::MediaLineLC( const RStringF& aMedia, |
|
483 const TDesC8& aFormatList ) const |
|
484 { |
|
485 return CSdpMediaField::NewLC( aMedia, |
|
486 NULL, |
|
487 MusAvaCapabilityContext::SDPStringL( |
|
488 SdpCodecStringConstants::EProtocolRtpAvp ), |
|
489 aFormatList ); |
|
490 } |
|
491 |
|
492 // ----------------------------------------------------------------------------- |
|
493 // CMusAvaCapability::RtpMapLineLC |
|
494 // ------------------------------------------------ ----------------------------- |
|
495 // |
|
496 CSdpFmtAttributeField* CMusAvaCapability::RtpMapLineLC( |
|
497 const TDesC8& aCodec, |
|
498 const TUint64 aPayloadType, |
|
499 const TUint64 aClockRate, |
|
500 const TDesC8& aParams ) |
|
501 { |
|
502 |
|
503 HBufC8* clockrate = HBufC8::NewLC( KMaxNumAsStringSize ); |
|
504 clockrate->Des().Num( aClockRate, EDecimal ); |
|
505 HBufC8* payload = HBufC8::NewLC( KMaxNumAsStringSize ); |
|
506 payload->Des().Num( aPayloadType, EDecimal ); |
|
507 |
|
508 |
|
509 TSdpRtpmapValue rtpmapValue( aCodec, |
|
510 *clockrate, |
|
511 aParams ); |
|
512 |
|
513 |
|
514 HBufC8* rtpmap = rtpmapValue.EncodeL(); |
|
515 CleanupStack::PushL( rtpmap ); |
|
516 |
|
517 CSdpFmtAttributeField* rtpmapAttribute = |
|
518 CSdpFmtAttributeField::NewL( MusAvaCapabilityContext::SDPStringL( |
|
519 SdpCodecStringConstants::EAttributeRtpmap ), |
|
520 *payload, |
|
521 *rtpmap ); |
|
522 |
|
523 CleanupStack::PopAndDestroy( rtpmap ); |
|
524 CleanupStack::PopAndDestroy( payload ); |
|
525 CleanupStack::PopAndDestroy( clockrate ); |
|
526 |
|
527 CleanupStack::PushL( rtpmapAttribute ); |
|
528 |
|
529 return rtpmapAttribute; |
|
530 } |
|
531 |
|
532 |
|
533 |
|