|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57" xml:lang="en"><title>Example |
|
13 of a SIP Client Resolver Plug-in</title><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>This is an example of a SIP Client Resolver plug-in called <codeph>CSimpleAppLauncher</codeph>. </p> |
|
15 <p>In this example, the plug-in capabilities are not defined in a resource |
|
16 file but are defined in the implementation as the <codeph>KCapabilities</codeph> literal |
|
17 descriptor. </p> |
|
18 <p>If capabilities are defined in the resource file instead of within the |
|
19 implementation, they are defined in the <codeph>opaque_data</codeph> field |
|
20 in XML format. See <xref href="GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57.dita#GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57/GUID-2B6A49E7-B483-59E2-B679-9828B483AB52">Example |
|
21 of capabilities definition in XML format</xref>. </p> |
|
22 <section id="GUID-1DF21E5C-9D66-5BBD-A1FD-91B5043D5D72"><title>Implementation |
|
23 of CSimpleAppLauncher using CSIPResolvedClient interface</title> <p><b> CSimpleAppLauncher.H </b> </p> <codeblock id="GUID-25F9D5DF-0D59-5236-8E04-641F36C0DEF8" xml:space="preserve">#include "SipResolvedClient.h" |
|
24 |
|
25 class CSimpleAppLauncher : public CSIPResolvedClient |
|
26 { |
|
27 public: // Constructors and destructor |
|
28 /** |
|
29 * Static constructor |
|
30 * @return An initialized instance of this class. |
|
31 */ |
|
32 static CSimpleAppLauncher* NewL(); |
|
33 |
|
34 /// Destructor |
|
35 ~CSimpleAppLauncher(); |
|
36 |
|
37 public: // from CSIPResolvedClient |
|
38 TUid ChannelL(RStringF aMethod, |
|
39 const TDesC8& aRequestUri, |
|
40 const RPointerArray<CSIPHeaderBase>& aHeaders, |
|
41 const TDesC8& aContent, |
|
42 const CSIPContentTypeHeader* aContentType=0); |
|
43 |
|
44 void ConnectL(TUid aUid); |
|
45 |
|
46 const TDesC8& Capabilities(); |
|
47 |
|
48 private: // Constructors |
|
49 |
|
50 inline CSimpleAppLauncher() {} |
|
51 |
|
52 // Second phase constructor |
|
53 void ConstructL(); |
|
54 }; |
|
55 </codeblock> <p><b> CSimpleAppLauncher.CPP </b> </p> <codeblock id="GUID-D7CF3E31-D2E1-5CF6-AAD0-6CE028EB9412" xml:space="preserve">#include "CSimpleAppLauncher.h" |
|
56 |
|
57 const TUid KMyApplicationUid = { 0x101F5D45 }; |
|
58 |
|
59 _LIT8(KCapabilities, |
|
60 "<SIP_CLIENT ALLOW_STARTING=\"YES\"><SIP_HEADERS>\ |
|
61 <ACCEPT value=\"text/plain\"/></SIP_HEADERS></SIP_CLIENT>"); |
|
62 |
|
63 // ----------------------------------------------------------------------------- |
|
64 // CSimpleAppLauncher::NewL |
|
65 // ----------------------------------------------------------------------------- |
|
66 // |
|
67 CSimpleAppLauncher* CSimpleAppLauncher::NewL() |
|
68 { |
|
69 CSimpleAppLauncher* self = new( ELeave ) CSimpleAppLauncher; |
|
70 CleanupStack::PushL( self ); |
|
71 self->ConstructL(); |
|
72 CleanupStack::Pop( self ); |
|
73 return self; |
|
74 } |
|
75 |
|
76 // ----------------------------------------------------------------------------- |
|
77 // CSimpleAppLauncher::ConstructL |
|
78 // ----------------------------------------------------------------------------- |
|
79 // |
|
80 void CSimpleAppLauncher::ConstructL() |
|
81 { |
|
82 } |
|
83 |
|
84 // ----------------------------------------------------------------------------- |
|
85 // CSimpleAppLauncher::~CSimpleAppLauncher |
|
86 // ----------------------------------------------------------------------------- |
|
87 // |
|
88 CSimpleAppLauncher::~CSimpleAppLauncher() |
|
89 { |
|
90 } |
|
91 |
|
92 // ----------------------------------------------------------------------------- |
|
93 // CSimpleAppLauncher::ChannelL |
|
94 // ----------------------------------------------------------------------------- |
|
95 // |
|
96 TUid CSimpleAppLauncher::ChannelL(RStringF /*aMethod*/, |
|
97 const TDesC8& /*aRequestUri*/, |
|
98 const RPointerArray<CSIPHeaderBase>& /*aHeaders*/, |
|
99 const TDesC8& /*aContent*/, |
|
100 const CSIPContentTypeHeader* /*aContentType*/) |
|
101 { |
|
102 // In the basic case application wants all the requests to itself |
|
103 return KMyApplicationUid; |
|
104 |
|
105 } |
|
106 |
|
107 // ----------------------------------------------------------------------------- |
|
108 // CSimpleAppLauncher::ConnectL |
|
109 // ----------------------------------------------------------------------------- |
|
110 // |
|
111 void CSimpleAppLauncher::ConnectL(TUid aUid) |
|
112 { |
|
113 // application specific starting logic that leads to |
|
114 // the connection with the SIP. The same UID must be |
|
115 // provided to SIP while invoking CSIP::NewL(). |
|
116 } |
|
117 |
|
118 |
|
119 // ----------------------------------------------------------------------------- |
|
120 // CSimpleAppLauncher::Capabilities |
|
121 // ----------------------------------------------------------------------------- |
|
122 // |
|
123 const TDesC8& CSimpleAppLauncher::Capabilities() |
|
124 { |
|
125 // if an application did not provide capabilities in the |
|
126 // ECOM rsc-file this function will be invoked by the |
|
127 // resolution logic implementation. |
|
128 return KCapabilities; |
|
129 } |
|
130 </codeblock> <p><b> 00000001.RSS </b> </p> <codeblock id="GUID-BA39D436-55CD-54AC-99F6-0AFDBE825E3F" xml:space="preserve">00000001.RSS |
|
131 #include <RegistryInfo.rh> |
|
132 |
|
133 RESOURCE REGISTRY_INFO theInfo |
|
134 { |
|
135 // UID for the DLL |
|
136 dll_uid = 0x00000001; |
|
137 // Declare array of interface info |
|
138 interfaces = |
|
139 { |
|
140 INTERFACE_INFO |
|
141 { |
|
142 // UID of interface that is implemented |
|
143 interface_uid = 0x102010DD; |
|
144 implementations = |
|
145 { |
|
146 IMPLEMENTATION_INFO |
|
147 { |
|
148 implementation_uid = 0x00000001; |
|
149 version_no = 1; |
|
150 default_data = "101F5D45"; // SIP client application UID SIPTestUI in this case) |
|
151 } |
|
152 }; |
|
153 } |
|
154 }; |
|
155 }</codeblock> <p id="GUID-2B6A49E7-B483-59E2-B679-9828B483AB52"><b>Example |
|
156 of capabilities definition in XML format</b> </p> <p>This is an example of |
|
157 defining capabilities in XML format. </p> <codeblock id="GUID-AD845CAF-ADC0-5C53-BF4A-E02D9D5E6A15" xml:space="preserve"><SIP_CLIENT ALLOW_STARTING="YES"> |
|
158 <SIP_HEADERS> |
|
159 <ACCEPT_CONTACT value="*;mobility="mobile";media="audio"" /> |
|
160 <ALLOW_EVENTS value="presence" /> |
|
161 <ACCEPT value="somecontent/type" /> |
|
162 <ACCEPT value="application/sdp" /> |
|
163 </SIP_HEADERS> |
|
164 <SDP_LINES> |
|
165 <LINE name="m" value="audio 30000 RTP/AVP 98" /> |
|
166 </SDP_LINES> |
|
167 </SIP_CLIENT> |
|
168 </codeblock> <p> <b>Note:</b> This XML file is an example to demonstrate how |
|
169 to define capabilities in XML format. The contents of this file are not related |
|
170 to the <codeph>CSimpleAppLauncher</codeph> example plug-in in anyway, as the |
|
171 capabilities for the example plug-in is proved. </p> </section> |
|
172 <section><title>Implementation of CSimpleAppLauncher2 using CSIPResolvedClient2 |
|
173 interface</title> <p>This is an example of SIP Client Resolver plug-in named <codeph>CSimpleAppLauncher2</codeph>. </p> <p><b>CSimpleAppLauncher2.h</b> </p> <codeblock id="GUID-AC545323-9326-506E-984C-CF831A3A6828" xml:space="preserve">#include "SipResolvedClient2.h" |
|
174 |
|
175 class CSimpleAppLauncher2 : public CSIPResolvedClient2 |
|
176 { |
|
177 public: // Constructors and destructor |
|
178 |
|
179 /** |
|
180 * Static constructor |
|
181 * @return An initialized instance of this class. |
|
182 */ |
|
183 static CSimpleAppLauncher2* NewL(); |
|
184 |
|
185 /// Destructor |
|
186 ~CSimpleAppLauncher2(); |
|
187 |
|
188 public: // from CSIPResolvedClient2 |
|
189 |
|
190 TBool MatchAcceptContactsL( |
|
191 RStringF aMethod, |
|
192 const CUri8& aRequestUri, |
|
193 const RPointerArray<CSIPHeaderBase>& aHeaders, |
|
194 const TDesC8& aContent, |
|
195 const CSIPContentTypeHeader* aContentType, |
|
196 TUid& aClientUid); |
|
197 |
|
198 TBool MatchEventL( |
|
199 RStringF aMethod, |
|
200 const CUri8& aRequestUri, |
|
201 const RPointerArray<CSIPHeaderBase>& aHeaders, |
|
202 const TDesC8& aContent, |
|
203 const CSIPContentTypeHeader* aContentType, |
|
204 TUid& aClientUid); |
|
205 |
|
206 TBool MatchRequestL( |
|
207 RStringF aMethod, |
|
208 const CUri8& aRequestUri, |
|
209 const RPointerArray<CSIPHeaderBase>& aHeaders, |
|
210 const TDesC8& aContent, |
|
211 const CSIPContentTypeHeader* aContentType, |
|
212 TUid& aClientUid ); |
|
213 |
|
214 TBool ConnectSupported() ; |
|
215 |
|
216 void ConnectL( const TUid& aClientUid ); |
|
217 |
|
218 void CancelConnect( const TUid& aClientUid ); |
|
219 |
|
220 RPointerArray<CSIPContentTypeHeader> SupportedContentTypesL(); |
|
221 |
|
222 RPointerArray<CSdpMediaField> SupportedSdpMediasL(); |
|
223 |
|
224 void AddClientSpecificHeadersForOptionsResponseL( |
|
225 RPointerArray<CSIPHeaderBase>& aHeaders ); |
|
226 |
|
227 private: // Constructors |
|
228 |
|
229 inline CSimpleAppLauncher2(){} |
|
230 |
|
231 // Second phase constructor |
|
232 void ConstructL(); |
|
233 |
|
234 private: //Data |
|
235 |
|
236 RPointerArray<CSIPAcceptContactHeader> iAcceptContactHeaders; |
|
237 CSIPEventHeader* iEvent; |
|
238 CSIPExtensionHeader* iExtensionHeader; |
|
239 }; |
|
240 </codeblock> <p><b>CSimpleAppLauncher2.cpp</b> </p> <codeblock id="GUID-C65A4DFA-C332-5096-B885-017E9C8E7722" xml:space="preserve">#include "CSimpleAppLauncher2.h" |
|
241 |
|
242 const TUid KResolvedClient2PluginUID = { 0x23456789 }; |
|
243 |
|
244 |
|
245 // ----------------------------------------------------------------------------- |
|
246 // CSimpleAppLauncher2::NewL |
|
247 // ----------------------------------------------------------------------------- |
|
248 // |
|
249 CSimpleAppLauncher2* CSimpleAppLauncher2::NewL() |
|
250 { |
|
251 CSimpleAppLauncher2* self = new( ELeave ) CSimpleAppLauncher2; |
|
252 CleanupStack::PushL( self ); |
|
253 self->ConstructL(); |
|
254 CleanupStack::Pop( self ); |
|
255 return self; |
|
256 } |
|
257 |
|
258 // ----------------------------------------------------------------------------- |
|
259 // CSimpleAppLauncher2::ConstructL |
|
260 // ----------------------------------------------------------------------------- |
|
261 // |
|
262 void CSimpleAppLauncher2::ConstructL() |
|
263 { |
|
264 _LIT8(KACValue, "*;+resolvedexample2"); |
|
265 iAcceptContactHeaders = CSIPAcceptContactHeader::DecodeL(KACValue()); |
|
266 _LIT8(KEventValue,"precense.winfo.jinfo.kinfo"); |
|
267 iEvent = CSIPEventHeader::DecodeL(KEventValue()); |
|
268 iExtensionHeader = CSIPExtensionHeader::NewL( _L8("ExtraHeader"), |
|
269 _L8("resolvedClient2")); |
|
270 } |
|
271 |
|
272 // ----------------------------------------------------------------------------- |
|
273 // CSimpleAppLauncher2::~CSimpleAppLauncher2 |
|
274 // ----------------------------------------------------------------------------- |
|
275 // |
|
276 CSimpleAppLauncher2::~CSimpleAppLauncher2() |
|
277 { |
|
278 iAcceptContactHeaders.ResetAndDestroy(); |
|
279 delete iEvent; |
|
280 delete iExtensionHeader; |
|
281 } |
|
282 |
|
283 // ----------------------------------------------------------------------------- |
|
284 // CSimpleAppLauncher2::MatchAcceptContactsL |
|
285 // From CSIPResolvedClient2 |
|
286 // ----------------------------------------------------------------------------- |
|
287 // |
|
288 TBool CSimpleAppLauncher2::MatchAcceptContactsL( |
|
289 RStringF /*aMethod*/, |
|
290 const CUri8& /*aRequestUri*/, |
|
291 const RPointerArray<CSIPHeaderBase>& aHeaders, |
|
292 const TDesC8& /*aContent*/, |
|
293 const CSIPContentTypeHeader* /*aContentType*/, |
|
294 TUid& aClientUid) |
|
295 { |
|
296 |
|
297 TBool match = EFalse; |
|
298 if ( iAcceptContactHeaders.Count() ) |
|
299 { |
|
300 CSIPAcceptContactHeader* acceptContact = |
|
301 static_cast<CSIPAcceptContactHeader*>(iAcceptContactHeaders[0]); |
|
302 for (TInt i = 0;i < aHeaders.Count() && !match;i++) |
|
303 { |
|
304 CSIPAcceptContactHeader* ac = |
|
305 static_cast<CSIPAcceptContactHeader*>(aHeaders[i]); |
|
306 if ( ac == acceptContact ) |
|
307 { |
|
308 match = ETrue; |
|
309 aClientUid.iUid = 0x23456789; |
|
310 } |
|
311 } |
|
312 } |
|
313 return match; |
|
314 } |
|
315 |
|
316 // ----------------------------------------------------------------------------- |
|
317 // CSimpleAppLauncher2::MatchEventL |
|
318 // From CSIPResolvedClient2 |
|
319 // ----------------------------------------------------------------------------- |
|
320 // |
|
321 TBool CSimpleAppLauncher2::MatchEventL( |
|
322 RStringF /*aMethod*/, |
|
323 const CUri8& /*aRequestUri*/, |
|
324 const RPointerArray<CSIPHeaderBase>& aHeaders, |
|
325 const TDesC8& /*aContent*/, |
|
326 const CSIPContentTypeHeader* /*aContentType*/, |
|
327 TUid& aClientUid) |
|
328 { |
|
329 TBool match = EFalse; |
|
330 if ( iEvent ) |
|
331 { |
|
332 for (TInt i = 0;i < aHeaders.Count() && !match;i++) |
|
333 { |
|
334 CSIPEventHeader* event = |
|
335 static_cast<CSIPEventHeader*>(aHeaders[i]); |
|
336 if ( event == iEvent ) |
|
337 { |
|
338 match = ETrue; |
|
339 aClientUid.iUid = 0x23456789; |
|
340 } |
|
341 } |
|
342 } |
|
343 return match; |
|
344 } |
|
345 |
|
346 // ----------------------------------------------------------------------------- |
|
347 // CSimpleAppLauncher2::MatchRequestL |
|
348 // From CSIPResolvedClient2 |
|
349 // ----------------------------------------------------------------------------- |
|
350 // |
|
351 TBool CSimpleAppLauncher2::MatchRequestL( |
|
352 RStringF /*aMethod*/, |
|
353 const CUri8& /*aRequestUri*/, |
|
354 const RPointerArray<CSIPHeaderBase>& aHeaders, |
|
355 const TDesC8& /*aContent*/, |
|
356 const CSIPContentTypeHeader* /*aContentType*/, |
|
357 TUid& aClientUid) |
|
358 { |
|
359 TBool match = EFalse; |
|
360 if ( iExtensionHeader ) |
|
361 { |
|
362 for (TInt i = 0;i < aHeaders.Count() && !match;i++) |
|
363 { |
|
364 CSIPExtensionHeader* extension = |
|
365 static_cast<CSIPExtensionHeader*>(aHeaders[i]); |
|
366 if ( iExtensionHeader->Name() == extension->Name() ) |
|
367 { |
|
368 match = ETrue; |
|
369 aClientUid.iUid = 0x23456789; |
|
370 } |
|
371 } |
|
372 } |
|
373 return match; |
|
374 } |
|
375 |
|
376 // ----------------------------------------------------------------------------- |
|
377 // CSimpleAppLauncher2::ConnectSupported |
|
378 // From CSIPResolvedClient2 |
|
379 // ----------------------------------------------------------------------------- |
|
380 // |
|
381 TBool CSimpleAppLauncher2::ConnectSupported() |
|
382 { |
|
383 return ETrue; |
|
384 } |
|
385 |
|
386 // ----------------------------------------------------------------------------- |
|
387 // CSimpleAppLauncher2::ConnectL |
|
388 // From CSIPResolvedClient2 |
|
389 // ----------------------------------------------------------------------------- |
|
390 // |
|
391 void CSimpleAppLauncher2::ConnectL( |
|
392 const TUid& aClientUid ) |
|
393 { |
|
394 // application specific starting logic that leads to |
|
395 // the connection with the SIP. The same UID must be |
|
396 // provided to SIP while invoking CSIP::NewL(). |
|
397 } |
|
398 |
|
399 // ----------------------------------------------------------------------------- |
|
400 // CSimpleAppLauncher2::CancelConnect |
|
401 // From CSIPResolvedClient2 |
|
402 // ----------------------------------------------------------------------------- |
|
403 // |
|
404 void CSimpleAppLauncher2::CancelConnect( |
|
405 const TUid& /*aClientUid*/ ) |
|
406 { |
|
407 } |
|
408 |
|
409 // ----------------------------------------------------------------------------- |
|
410 // CSimpleAppLauncher2::SupportedContentTypesL |
|
411 // From CSIPResolvedClient2 |
|
412 // ----------------------------------------------------------------------------- |
|
413 // |
|
414 RPointerArray<CSIPContentTypeHeader> |
|
415 CSimpleAppLauncher2::SupportedContentTypesL() |
|
416 { |
|
417 RPointerArray<CSIPContentTypeHeader> headers; |
|
418 _LIT8 (KAppWithSdp, "application/sdp"); |
|
419 CSIPContentTypeHeader* contentTypeHeader = |
|
420 CSIPContentTypeHeader::DecodeL(KAppWithSdp()); |
|
421 CleanupStack::PushL( contentTypeHeader ); |
|
422 headers.AppendL( contentTypeHeader ); |
|
423 CleanupStack::Pop( contentTypeHeader ); |
|
424 return headers; |
|
425 } |
|
426 |
|
427 // ----------------------------------------------------------------------------- |
|
428 // CSimpleAppLauncher2::SupportedSdpMediasL |
|
429 // From CSIPResolvedClient2 |
|
430 // ----------------------------------------------------------------------------- |
|
431 // |
|
432 RPointerArray<CSdpMediaField> |
|
433 CSimpleAppLauncher2::SupportedSdpMediasL() |
|
434 { |
|
435 RStringPool sdpStrPool = SdpCodecStringPool::StringPoolL(); |
|
436 RStringF media = sdpStrPool.OpenFStringL(_L8("audio")); |
|
437 CleanupClosePushL(media); |
|
438 RStringF protocol = sdpStrPool.OpenFStringL(_L8("RTP/AVP")); |
|
439 CleanupClosePushL(protocol); |
|
440 CSdpMediaField* mediafield = |
|
441 CSdpMediaField::NewL(media,0,protocol,_L8("formatlist")); |
|
442 CleanupStack::Pop(2);//media,protocol |
|
443 media.Close(); |
|
444 protocol.Close(); |
|
445 CleanupStack::PushL(mediafield); |
|
446 RPointerArray<CSdpMediaField> headers; |
|
447 headers.AppendL(mediafield); |
|
448 CleanupStack::Pop(mediafield); |
|
449 return headers; |
|
450 } |
|
451 |
|
452 // ----------------------------------------------------------------------------- |
|
453 // CSimpleAppLauncher2::AddClientSpecificHeadersForOptionsResponseL |
|
454 // From CSIPResolvedClient2 |
|
455 // ----------------------------------------------------------------------------- |
|
456 // |
|
457 void CSimpleAppLauncher2::AddClientSpecificHeadersForOptionsResponseL( |
|
458 RPointerArray<CSIPHeaderBase>& aHeaders ) |
|
459 { |
|
460 CSIPExtensionHeader* extHeader = |
|
461 CSIPExtensionHeader::NewL( _L8("ExtraHeader"), |
|
462 _L8("resolvedClient2")); |
|
463 CleanupStack::PushL( extHeader ); |
|
464 TBool found(EFalse); |
|
465 for ( TInt i = 0;i < aHeaders.Count() && !found;i++ ) |
|
466 { |
|
467 if ( aHeaders[i]->IsExtensionHeader() ) |
|
468 { |
|
469 //It is plug-ins responsibility to check that the new extension |
|
470 //header is not yet exsisiting in aHeaders array. |
|
471 |
|
472 if ( (static_cast <CSIPExtensionHeader*> (aHeaders[i]) )->Value() |
|
473 == extHeader->Value() &&(static_cast <CSIPExtensionHeader*> |
|
474 (aHeaders[i]) )->Name() == extHeader->Name() ) |
|
475 { |
|
476 found = ETrue; |
|
477 CleanupStack::Pop( extHeader ); |
|
478 delete extHeader; |
|
479 } |
|
480 } |
|
481 } |
|
482 if ( !found ) |
|
483 { |
|
484 aHeaders.AppendL( extHeader ); |
|
485 CleanupStack::Pop( extHeader ); |
|
486 } |
|
487 } |
|
488 </codeblock> </section> |
|
489 </conbody></concept> |