1 /* |
|
2 * Copyright (c) 2006-2010 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: Transfer controller class, transfer is controlled through |
|
15 * this class |
|
16 * |
|
17 */ |
|
18 |
|
19 #include <mceinrefer.h> // CMceInRefer |
|
20 #include <mceinevent.h> // CMceEvent, CMceInEvent |
|
21 #include <mcetransactiondatacontainer.h> // TMceTransactionDataContainer |
|
22 |
|
23 #include "svptransfercontroller.h" |
|
24 #include "svptransferstatecontext.h" |
|
25 #include "svplogger.h" |
|
26 #include "svpsessionbase.h" // CSVPSessionBase |
|
27 #include "svpsipconsts.h" |
|
28 #include "svpconsts.h" |
|
29 |
|
30 // --------------------------------------------------------------------------- |
|
31 // CSVPTransferController::CSVPTransferController |
|
32 // --------------------------------------------------------------------------- |
|
33 // |
|
34 CSVPTransferController::CSVPTransferController() : |
|
35 iTransferContext (NULL), |
|
36 iCCPTransferObserver (NULL), |
|
37 iAccepted( EFalse ) |
|
38 { |
|
39 } |
|
40 |
|
41 // --------------------------------------------------------------------------- |
|
42 // CSVPTransferController::ConstructL |
|
43 // --------------------------------------------------------------------------- |
|
44 // |
|
45 void CSVPTransferController::ConstructL( |
|
46 CMceSession* aMceSession, |
|
47 CSVPSessionBase* aSVPSession, |
|
48 TMceTransactionDataContainer& aContainer, |
|
49 MSVPTransferObserver& aObserver ) |
|
50 { |
|
51 // Transfer state context |
|
52 iTransferContext = CSVPTransferStateContext::NewL( |
|
53 aMceSession, aSVPSession, |
|
54 aContainer, aObserver ); |
|
55 } |
|
56 |
|
57 |
|
58 // --------------------------------------------------------------------------- |
|
59 // CSVPTransferController::NewL |
|
60 // --------------------------------------------------------------------------- |
|
61 // |
|
62 CSVPTransferController* CSVPTransferController::NewL( |
|
63 CMceSession* aMceSession, |
|
64 CSVPSessionBase* aSVPSession, |
|
65 TMceTransactionDataContainer& aContainer, |
|
66 MSVPTransferObserver& aObserver ) |
|
67 { |
|
68 CSVPTransferController* self = CSVPTransferController::NewLC( |
|
69 aMceSession, |
|
70 aSVPSession, |
|
71 aContainer, |
|
72 aObserver ); |
|
73 CleanupStack::Pop( self ); |
|
74 return self; |
|
75 } |
|
76 |
|
77 |
|
78 // --------------------------------------------------------------------------- |
|
79 // CSVPTransferController::NewLC |
|
80 // --------------------------------------------------------------------------- |
|
81 // |
|
82 CSVPTransferController* CSVPTransferController::NewLC( |
|
83 CMceSession* aMceSession, |
|
84 CSVPSessionBase* aSVPSession, |
|
85 TMceTransactionDataContainer& aContainer, |
|
86 MSVPTransferObserver& aObserver ) |
|
87 { |
|
88 CSVPTransferController* self = new( ELeave ) CSVPTransferController; |
|
89 CleanupStack::PushL( self ); |
|
90 self->ConstructL( aMceSession, aSVPSession, aContainer, aObserver ); |
|
91 return self; |
|
92 } |
|
93 |
|
94 |
|
95 // --------------------------------------------------------------------------- |
|
96 // CSVPTransferController::~CSVPTransferController |
|
97 // --------------------------------------------------------------------------- |
|
98 // |
|
99 CSVPTransferController::~CSVPTransferController() |
|
100 { |
|
101 delete iTransferContext; |
|
102 } |
|
103 |
|
104 |
|
105 // --------------------------------------------------------------------------- |
|
106 // Handle mce event observer notify events. |
|
107 // The state of the event has changed. |
|
108 // --------------------------------------------------------------------------- |
|
109 // |
|
110 void CSVPTransferController::HandleEventStateChangedL( |
|
111 CMceEvent& /* aEvent */, |
|
112 TInt aStatusCode ) |
|
113 { |
|
114 if ( KSVPOKVal == aStatusCode ) |
|
115 { |
|
116 if ( iTransferContext->IsAttended() ) |
|
117 { |
|
118 SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: KSVPOKVal & attended" ); |
|
119 if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState()) |
|
120 { |
|
121 // F25 OK received - already acccepted |
|
122 // leave for not to create new session later |
|
123 SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: transfer in progress"); |
|
124 User::Leave( KSVPErrTransferInProgress ); |
|
125 } |
|
126 |
|
127 // F18 OK received as response for "trying" |
|
128 // Set and apply the next state - accepted |
|
129 iTransferContext->SetCurrentStateL( KSVPTransferAcceptedStateIndex ); |
|
130 iTransferContext->ApplyCurrentStateL(); |
|
131 SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL:ApplyCurrentStateL done" ); |
|
132 } |
|
133 else // unattended transfer |
|
134 { |
|
135 SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: KSVPOKVal unattended" ); |
|
136 if ( iTransferContext->CheckIsSessionRemoteHold() && |
|
137 KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() ) |
|
138 { |
|
139 // Transferer has put transferee on hold before sending refer |
|
140 SVPDEBUG1( "CSVPTransferController::HandleEventStateChangedL: Snom or similar as transferer" ); |
|
141 SendNotifyL( aStatusCode ); // 200 OK |
|
142 } |
|
143 } |
|
144 } |
|
145 else |
|
146 { |
|
147 SVPDEBUG2("CSVPTransferController::HandleEventStateChangedL: aStatusCode = %d", |
|
148 aStatusCode); |
|
149 } |
|
150 SVPDEBUG1("CSVPTransferController::HandleEventStateChangedL: Out"); |
|
151 } |
|
152 |
|
153 // --------------------------------------------------------------------------- |
|
154 // CSVPTransferController::NotifyReceivedL |
|
155 // --------------------------------------------------------------------------- |
|
156 // |
|
157 void CSVPTransferController::NotifyReceivedL( |
|
158 CMceEvent& aEvent, |
|
159 TMceTransactionDataContainer* aContainer ) |
|
160 { |
|
161 SVPDEBUG1("CSVPTransferController::NotifyReceivedL: In"); |
|
162 |
|
163 // check data container and match the event to the active refer event |
|
164 if ( aContainer && iTransferContext->MceEvent() == &aEvent ) |
|
165 { |
|
166 TInt statusCode = aContainer->GetStatusCode(); |
|
167 HBufC8* content = aContainer->GetContent(); |
|
168 |
|
169 SVPDEBUG2( "CSVPTransferController::NotifyReceivedL:\ |
|
170 statusCode: %d", statusCode ); |
|
171 SVPDEBUG2( "CSVPTransferController::NotifyReceivedL:\ |
|
172 aContainer->GetContent()->Length(): %d", content->Length() ); |
|
173 |
|
174 if ( !content->Find( TPtrC8( KSVPNotifyTrying ) ) ) |
|
175 { |
|
176 if ( iTransferContext->IsAttended() ) |
|
177 { |
|
178 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\ |
|
179 SIP/2.0 100 Trying" ); |
|
180 |
|
181 // Attended transfer (F17) NOTIFY , transferee is trying establish new session. |
|
182 // Check if 202 Accepted already received |
|
183 if ( iAccepted ) |
|
184 { |
|
185 // Stop the refer timer |
|
186 iTransferContext->StopReferTimer( ); |
|
187 // Set and apply the next state - accepted |
|
188 iTransferContext->SetCurrentStateL( |
|
189 KSVPTransferAcceptedStateIndex ); |
|
190 iTransferContext->ApplyCurrentStateL(); |
|
191 } |
|
192 } |
|
193 else |
|
194 { |
|
195 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended case:\ |
|
196 SIP/2.0 100 Trying" ); |
|
197 |
|
198 // Check if 202 Accepted already received |
|
199 if ( iAccepted ) |
|
200 { |
|
201 // Stop the refer timer |
|
202 iTransferContext->StopReferTimer( ); |
|
203 |
|
204 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: is accepted" ); |
|
205 |
|
206 // Unattended transfer: F7 NOTIFY, display "transferred" note |
|
207 if( iCCPTransferObserver ) |
|
208 { |
|
209 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" ); |
|
210 iCCPTransferObserver->TransferEventOccurred( |
|
211 MCCPTransferObserver::ECCPLocalTransfer ); |
|
212 } |
|
213 |
|
214 // Set and apply the next state - accepted |
|
215 iTransferContext->SetCurrentStateL( |
|
216 KSVPTransferAcceptedStateIndex ); |
|
217 iTransferContext->ApplyCurrentStateL(); |
|
218 |
|
219 iTransferContext->SetCurrentStateL( |
|
220 KSVPTransferTerminatingStateIndex ); |
|
221 iTransferContext->ApplyCurrentStateL(); |
|
222 // Unattended transfer is ok, hangup the session |
|
223 iTransferContext->TransferObserver().TransferNotification( |
|
224 ESVPTransferOKHangUp ); |
|
225 } |
|
226 } |
|
227 } |
|
228 else if ( !content->Find( TPtrC8( KSVPNotifyOK ) ) || |
|
229 !content->Find( TPtrC8( KSVPNotifyOk2 ) ) ) |
|
230 { |
|
231 if ( iTransferContext->IsAttended() ) |
|
232 { |
|
233 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\ |
|
234 SIP/2.0 200 OK" ); |
|
235 |
|
236 // Attended transfer (F24) 200 OK |
|
237 if( iCCPTransferObserver ) |
|
238 { |
|
239 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" ); |
|
240 iCCPTransferObserver->TransferEventOccurred( |
|
241 MCCPTransferObserver::ECCPLocalTransfer ); |
|
242 } |
|
243 |
|
244 // Set and apply the next state - terminating |
|
245 iTransferContext->SetCurrentStateL( |
|
246 KSVPTransferTerminatingStateIndex ); |
|
247 iTransferContext->ApplyCurrentStateL(); |
|
248 |
|
249 // Attended transfer is ok, hangup the session |
|
250 iTransferContext->TransferObserver().TransferNotification( |
|
251 ESVPTransferOKHangUp ); |
|
252 } |
|
253 else |
|
254 { |
|
255 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended: SIP/2.0 200 OK" ); |
|
256 } |
|
257 } |
|
258 else if ( ( !content->Find( TPtrC8( KSVPNotifyRinging ) ) || |
|
259 !content->Find( TPtrC8( KSVPNotifyRinging183 ) ) ) && |
|
260 !iTransferContext->IsAttended()) |
|
261 { |
|
262 // Polycom send Ringing instead of Trying in unattended case. |
|
263 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended and Ringing" ); |
|
264 |
|
265 // Check if 202 Accepted already received |
|
266 if ( iAccepted ) |
|
267 { |
|
268 // Stop the refer timer |
|
269 iTransferContext->StopReferTimer( ); |
|
270 |
|
271 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: Polycom case" ); |
|
272 |
|
273 // Unattended transfer: display "transferred" note |
|
274 if( iCCPTransferObserver ) |
|
275 { |
|
276 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" ); |
|
277 iCCPTransferObserver->TransferEventOccurred( |
|
278 MCCPTransferObserver::ECCPLocalTransfer ); |
|
279 } |
|
280 |
|
281 // Set and apply the next state - accepted |
|
282 iTransferContext->SetCurrentStateL( |
|
283 KSVPTransferAcceptedStateIndex ); |
|
284 iTransferContext->ApplyCurrentStateL(); |
|
285 |
|
286 iTransferContext->SetCurrentStateL( |
|
287 KSVPTransferTerminatingStateIndex ); |
|
288 iTransferContext->ApplyCurrentStateL(); |
|
289 // Unattended transfer is ok, hangup the session |
|
290 iTransferContext->TransferObserver().TransferNotification( |
|
291 ESVPTransferOKHangUp ); |
|
292 } |
|
293 } |
|
294 else if ( !content->Find( TPtrC8( KSVPNotifyServiceUnavailable ) ) ) |
|
295 { |
|
296 // Notify that comes after the accepted refer, if |
|
297 // the (wrong) address of the refer cannot be reached. |
|
298 if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() ) |
|
299 { |
|
300 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503 -> ECCPTransferFailed"); |
|
301 |
|
302 // Set and apply the next state - terminating |
|
303 iTransferContext->SetCurrentStateL( |
|
304 KSVPTransferTerminatingStateIndex ); |
|
305 iTransferContext->ApplyCurrentStateL(); |
|
306 |
|
307 // Transfer fails, notify client. |
|
308 iTransferContext->TransferObserver().TransferNotification( |
|
309 ESVPTransferDecline ); |
|
310 } |
|
311 else |
|
312 { |
|
313 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503."); |
|
314 } |
|
315 } |
|
316 else |
|
317 { |
|
318 SVPDEBUG1("CSVPTransferController::NotifyReceivedL:\ |
|
319 Unhandled container content"); |
|
320 } |
|
321 |
|
322 // Ownership transferred here |
|
323 delete content; |
|
324 } |
|
325 |
|
326 SVPDEBUG1("CSVPTransferController::NotifyReceivedL: Out"); |
|
327 } |
|
328 |
|
329 |
|
330 // --------------------------------------------------------------------------- |
|
331 // CSVPTransferController::HandleReferStateChangeL |
|
332 // --------------------------------------------------------------------------- |
|
333 // |
|
334 void CSVPTransferController::HandleReferStateChangeL( CMceRefer& aRefer, |
|
335 TInt aStatusCode ) |
|
336 { |
|
337 SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() In"); |
|
338 |
|
339 if ( iTransferContext->MceRefer() == &aRefer ) |
|
340 { |
|
341 if ( KSVPAcceptedVal == aStatusCode ) |
|
342 { |
|
343 // Accepted unattended F6, Attended F16 |
|
344 SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Accept: %i", |
|
345 KSVPAcceptedVal ); |
|
346 |
|
347 // Display "transferring" note |
|
348 if( iCCPTransferObserver ) |
|
349 { |
|
350 SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL, send remote transferring" ); |
|
351 iCCPTransferObserver->TransferEventOccurred( |
|
352 MCCPTransferObserver::ECCPRemoteTransferring ); |
|
353 } |
|
354 // Continue acceptance when also notify F7 / F17 "trying" received |
|
355 iAccepted = ETrue; |
|
356 } |
|
357 else if ( ( KSVPBadRequestVal <= aStatusCode && |
|
358 KSVPRequestPendingVal >= aStatusCode ) || |
|
359 KSVPDeclineVal == aStatusCode || |
|
360 KSVPServerInternalErrorVal == aStatusCode || |
|
361 KSVPPreconditionFailureVal == aStatusCode ) |
|
362 { |
|
363 // Decline, Request Failure 4xx or Server Failure 5xx |
|
364 SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Code: %i", aStatusCode ); |
|
365 // Stop the refer timer |
|
366 iTransferContext->StopReferTimer( ); |
|
367 |
|
368 // Set and apply the next state - terminating |
|
369 iTransferContext->SetCurrentStateL( |
|
370 KSVPTransferTerminatingStateIndex ); |
|
371 iTransferContext->ApplyCurrentStateL(); |
|
372 |
|
373 // Notify the observer about the decline. |
|
374 iTransferContext->TransferObserver().TransferNotification( |
|
375 ESVPTransferDecline ); |
|
376 } |
|
377 |
|
378 else |
|
379 { |
|
380 // Not handled |
|
381 SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: \ |
|
382 Unknown StatusCode: %i", aStatusCode ); |
|
383 } |
|
384 } |
|
385 else |
|
386 { |
|
387 // Unknown refer - not handled |
|
388 SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL: \ |
|
389 Unknown refer"); |
|
390 } |
|
391 |
|
392 SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() Out"); |
|
393 } |
|
394 |
|
395 |
|
396 // --------------------------------------------------------------------------- |
|
397 // CSVPTransferController::IncomingReferL |
|
398 // --------------------------------------------------------------------------- |
|
399 // |
|
400 void CSVPTransferController::IncomingReferL( CMceInRefer* aRefer, |
|
401 const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer ) |
|
402 { |
|
403 SVPDEBUG1( "CSVPTransferController::IncomingReferL In" ) |
|
404 |
|
405 // Is new incoming refer handling possible |
|
406 if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() ) |
|
407 { |
|
408 SVPDEBUG1( "CSVPTransferController::IncomingReferL: allowed" ) |
|
409 |
|
410 iTransferContext->SetMceRefer( static_cast<CMceRefer*>( aRefer ) ); |
|
411 iTransferContext->SetIncomingReferToL( aReferTo ); |
|
412 CDesC8Array* headers = aContainer->GetHeaders();// get headers |
|
413 |
|
414 if ( headers ) |
|
415 { |
|
416 TBool found = EFalse; |
|
417 |
|
418 for( TInt i = 0; i < headers->MdcaCount() && !found; i++ ) |
|
419 { |
|
420 TPtrC8 tmpHeader = headers->MdcaPoint( i ); |
|
421 |
|
422 if ( KErrNotFound != tmpHeader.FindF( KSVPReferredBy ) ) |
|
423 { |
|
424 SVPDEBUG1( "KSVPReferredBy found" ) |
|
425 found = ETrue; |
|
426 iTransferContext->SetIncomingReferredByL( tmpHeader ); |
|
427 } |
|
428 } |
|
429 } |
|
430 |
|
431 delete headers; |
|
432 headers = NULL; |
|
433 } |
|
434 |
|
435 else if ( KSVPTransferPendingStateIndex == iTransferContext->CurrentState() ) |
|
436 { |
|
437 SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed \ |
|
438 -> ignore" ) |
|
439 User::Leave( KSVPErrTransferInProgress ); |
|
440 } |
|
441 |
|
442 else |
|
443 { |
|
444 SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed" ) |
|
445 User::Leave( KSVPErrTransferStateError ); |
|
446 } |
|
447 |
|
448 if ( iTransferContext->IsAttended() ) |
|
449 { |
|
450 SVPDEBUG1( "CSVPTransferController::IncomingReferL: Attended case, send accept" ) |
|
451 |
|
452 // send trying notification and wait respond for it |
|
453 CMceInEvent* inEvent = NULL; |
|
454 |
|
455 TRAPD( acceptError, inEvent = static_cast<CMceInRefer*>( |
|
456 iTransferContext->MceRefer() )->AcceptL() ); |
|
457 |
|
458 if ( KErrNone == acceptError ) |
|
459 { |
|
460 // Apply state, changes to next state (pending) |
|
461 SVPDEBUG1( "CSVPTransferController::IncomingReferL: pending state" ) |
|
462 iTransferContext->SetMceEvent( static_cast<CMceEvent*>( inEvent ) ); |
|
463 iTransferContext->ApplyCurrentStateL(); |
|
464 } |
|
465 else |
|
466 { |
|
467 // Set and apply the next state - terminating |
|
468 SVPDEBUG2("CSVPTransferController::IncomingReferL: acc fails = %d", acceptError ) |
|
469 iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex ); |
|
470 iTransferContext->ApplyCurrentStateL(); |
|
471 } |
|
472 } |
|
473 else |
|
474 { |
|
475 // Apply state, changes to next state (pending) |
|
476 SVPDEBUG1( "CSVPTransferController::IncomingReferL: UnAttended case pending" ) |
|
477 iTransferContext->ApplyCurrentStateL(); |
|
478 } |
|
479 |
|
480 SVPDEBUG1( "CSVPTransferController::IncomingReferL Out" ) |
|
481 } |
|
482 |
|
483 // --------------------------------------------------------------------------- |
|
484 // CSVPTransferController::IsMceRefer |
|
485 // --------------------------------------------------------------------------- |
|
486 // |
|
487 TBool CSVPTransferController::IsMceRefer( CMceRefer& aRefer ) |
|
488 { |
|
489 return ( iTransferContext->MceRefer() == &aRefer ); |
|
490 } |
|
491 |
|
492 // --------------------------------------------------------------------------- |
|
493 // CSVPTransferController::IsAttended |
|
494 // --------------------------------------------------------------------------- |
|
495 // |
|
496 TBool CSVPTransferController::IsAttended( ) |
|
497 { |
|
498 return ( iTransferContext->IsAttended() ); |
|
499 } |
|
500 |
|
501 // --------------------------------------------------------------------------- |
|
502 // CSVPTransferController::SetTransferDataL |
|
503 // --------------------------------------------------------------------------- |
|
504 // |
|
505 void CSVPTransferController::SetTransferDataL( CDesC8Array* aUserAgentHeaders, |
|
506 TInt aSecureStatus ) |
|
507 { |
|
508 SVPDEBUG1(" CSVPTransferController::SetTransferDataL" ); |
|
509 iTransferContext->SetTransferDataL( aUserAgentHeaders, aSecureStatus ); |
|
510 } |
|
511 |
|
512 // --------------------------------------------------------------------------- |
|
513 // CSVPTransferController::SetMceSessionObject |
|
514 // --------------------------------------------------------------------------- |
|
515 // |
|
516 void CSVPTransferController::SetMceSessionObject( CMceSession* aSession ) |
|
517 { |
|
518 iTransferContext->SetMceSessionObject( aSession ); |
|
519 } |
|
520 |
|
521 // --------------------------------------------------------------------------- |
|
522 // CSVPTransferController::SendNotifyL |
|
523 // --------------------------------------------------------------------------- |
|
524 // |
|
525 void CSVPTransferController::SendNotifyL( TInt aStatusCode ) |
|
526 { |
|
527 SVPDEBUG2("CSVPTransferController::SendNotifyL() code = %d", aStatusCode); |
|
528 |
|
529 CMceInEvent* inEvent = static_cast< CMceInEvent* > ( |
|
530 iTransferContext->MceEvent()); |
|
531 if (inEvent) |
|
532 { |
|
533 HBufC8* contentType = KSVPMessageSipfrag().AllocLC(); //message/sipfrag |
|
534 HBufC8* content = NULL; |
|
535 |
|
536 if (KSVPOKVal == aStatusCode ) |
|
537 { |
|
538 content = KSVPNotifyOK().AllocLC(); // "SIP/2.0 200 OK" |
|
539 } |
|
540 else if ( KSVPNotFoundVal == aStatusCode || |
|
541 KSVPBusyHereVal == aStatusCode || |
|
542 KSVPDeclineVal == aStatusCode ) |
|
543 { |
|
544 content = KSVPNotifyServiceUnavailable().AllocLC(); // "503" |
|
545 } |
|
546 else |
|
547 { |
|
548 SVPDEBUG2("CSVPTransferController::SendNotifyL unknown aStatusCode = %d", aStatusCode); |
|
549 content = KSVPNotifyServiceUnavailable().AllocLC(); // "503" |
|
550 } |
|
551 |
|
552 CDesC8Array* headers = NULL; |
|
553 headers = new( ELeave ) CDesC8ArrayFlat( KSVPContactArrayGranularity ); |
|
554 CleanupStack::PushL( headers ); |
|
555 headers->AppendL( KSVPSubsStateTerminated ); |
|
556 |
|
557 // Notify is sent to transferer (unattended msg F15, attended msg F24) |
|
558 TRAPD( errNotify, inEvent->TerminateL( headers, contentType, content ) ); |
|
559 |
|
560 if ( KErrNone == errNotify ) |
|
561 { |
|
562 SVPDEBUG1("CSVPTransferController::SendNotifyL, notify sending OK"); |
|
563 CleanupStack::Pop( 3, contentType ); // headers, content, contentType |
|
564 } |
|
565 else |
|
566 { |
|
567 // error handling |
|
568 SVPDEBUG2("CSVPTransferController::SendNotifyL: errNotify = %d", errNotify ); |
|
569 CleanupStack::PopAndDestroy( 3, contentType ); // headers, content, contentType |
|
570 } |
|
571 } |
|
572 |
|
573 if ( iTransferContext->IsAttended() ) |
|
574 { |
|
575 SVPDEBUG1("CSVPTransferController::SendNotifyL() Attended done"); |
|
576 } |
|
577 else |
|
578 { |
|
579 SVPDEBUG1("CSVPTransferController::SendNotifyL() UnAttended to terminating state"); |
|
580 // Finish unattended incoming transfer sequence |
|
581 // Set and apply the next state - terminating |
|
582 iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex ); |
|
583 iTransferContext->ApplyCurrentStateL(); |
|
584 } |
|
585 |
|
586 SVPDEBUG1("CSVPTransferController::SendNotifyL() Out"); |
|
587 } |
|
588 |
|
589 // --------------------------------------------------------------------------- |
|
590 // CSVPTransferController::IsIncomingTransfer |
|
591 // --------------------------------------------------------------------------- |
|
592 // |
|
593 TBool CSVPTransferController::IsIncomingTransfer() |
|
594 { |
|
595 SVPDEBUG2("CSVPTransferController::IsIncomingTransfer = %d", |
|
596 iTransferContext->IsIncoming() ); |
|
597 return iTransferContext->IsIncoming(); |
|
598 } |
|
599 |
|
600 // --------------------------------------------------------------------------- |
|
601 // CSVPTransferController::TerminateTransfer |
|
602 // --------------------------------------------------------------------------- |
|
603 // |
|
604 void CSVPTransferController::TerminateTransfer() |
|
605 { |
|
606 SVPDEBUG1("CSVPTransferController::TerminateTransfer" ) |
|
607 TRAP_IGNORE( TerminateTransferL() ); |
|
608 } |
|
609 |
|
610 // --------------------------------------------------------------------------- |
|
611 // CSVPTransferController::TerminateTransferL |
|
612 // --------------------------------------------------------------------------- |
|
613 // |
|
614 void CSVPTransferController::TerminateTransferL() |
|
615 { |
|
616 iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex ); |
|
617 iTransferContext->ApplyCurrentStateL(); |
|
618 } |
|
619 |
|
620 // --------------------------------------------------------------------------- |
|
621 // CSVPTransferController::AttendedTransfer |
|
622 // --------------------------------------------------------------------------- |
|
623 // |
|
624 TInt CSVPTransferController::AttendedTransfer( MCCPCall& aTransferTargetCall ) |
|
625 { |
|
626 SVPDEBUG1( "CSVPTransferController::AttendedTransfer call IN" ); |
|
627 TRAPD( transError, TransferL( &aTransferTargetCall, KNullDesC, ETrue )); |
|
628 SVPDEBUG2( "CSVPTransferController::AttendedTransfer A return: %d", transError ); |
|
629 return transError; |
|
630 } |
|
631 |
|
632 // --------------------------------------------------------------------------- |
|
633 // CSVPTransferController::AttendedTransfer |
|
634 // --------------------------------------------------------------------------- |
|
635 // |
|
636 TInt CSVPTransferController::AttendedTransfer( const TDesC& aTransferTarget ) |
|
637 { |
|
638 SVPDEBUG1( "CSVPTransferController::AttendedTransfer target IN" ); |
|
639 TRAPD( transError, TransferL( NULL, aTransferTarget, ETrue )); |
|
640 SVPDEBUG2( "CSVPTransferController::AttendedTransfer B return: %d", transError ); |
|
641 return transError; |
|
642 } |
|
643 |
|
644 // --------------------------------------------------------------------------- |
|
645 // CSVPTransferController::UnattendedTransfer |
|
646 // --------------------------------------------------------------------------- |
|
647 // |
|
648 TInt CSVPTransferController::UnattendedTransfer( const TDesC& aTransferTarget ) |
|
649 { |
|
650 SVPDEBUG1( "CSVPTransferController::UnattendedTransfer IN" ); |
|
651 TRAPD( transError, TransferL( NULL, aTransferTarget, EFalse )); |
|
652 SVPDEBUG2( "CSVPTransferController::UnattendedTransfer return: %d", transError ); |
|
653 return transError; |
|
654 } |
|
655 |
|
656 // --------------------------------------------------------------------------- |
|
657 // CSVPTransferController::AcceptTransfer |
|
658 // --------------------------------------------------------------------------- |
|
659 // |
|
660 TInt CSVPTransferController::AcceptTransfer( const TBool aAccept ) |
|
661 { |
|
662 SVPDEBUG2("CSVPTransferController::AcceptTransfer() IN aAccept = \ |
|
663 %d", aAccept); |
|
664 TInt acceptError = KErrNone; |
|
665 TInt stateError = KErrNone; |
|
666 TInt currentState = iTransferContext->CurrentState(); |
|
667 CMceInEvent* inEvent(NULL); |
|
668 |
|
669 // Is state "pending" |
|
670 if ( KSVPTransferPendingStateIndex == currentState ) |
|
671 { |
|
672 if ( aAccept ) |
|
673 { |
|
674 TRAP( acceptError, ( inEvent = static_cast< CMceInRefer* > (iTransferContext->MceRefer())->AcceptL())); |
|
675 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
676 AcceptL = %d", acceptError); |
|
677 } |
|
678 else |
|
679 { |
|
680 SVPDEBUG1("CSVPTransferController::AcceptTransfer() reject"); |
|
681 TRAP( acceptError, ( static_cast< CMceInRefer* > (iTransferContext->MceRefer())->RejectL()) ); |
|
682 } |
|
683 |
|
684 if ( KErrNone == acceptError ) |
|
685 { |
|
686 if ( aAccept ) |
|
687 { |
|
688 // Set the received event |
|
689 iTransferContext->SetMceEvent(static_cast< CMceEvent* >(inEvent)); |
|
690 |
|
691 // Set and apply the next state - accepted |
|
692 TRAP( acceptError, |
|
693 iTransferContext->SetCurrentStateL( |
|
694 KSVPTransferAcceptedStateIndex ); |
|
695 iTransferContext->ApplyCurrentStateL(); |
|
696 ); |
|
697 } |
|
698 else |
|
699 { |
|
700 // Set and apply the next state - terminating |
|
701 TRAP( acceptError, |
|
702 iTransferContext->SetCurrentStateL( |
|
703 KSVPTransferTerminatingStateIndex ); |
|
704 iTransferContext->ApplyCurrentStateL(); |
|
705 ); |
|
706 } |
|
707 } |
|
708 else |
|
709 { |
|
710 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
711 fails = %d", acceptError); |
|
712 // Set and apply the next state - terminating |
|
713 TRAP( stateError, |
|
714 iTransferContext->SetCurrentStateL( |
|
715 KSVPTransferTerminatingStateIndex ); |
|
716 iTransferContext->ApplyCurrentStateL(); |
|
717 ); |
|
718 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
719 stateError = %d", stateError); |
|
720 } |
|
721 } |
|
722 else |
|
723 { |
|
724 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
725 current state is not pending: %d", currentState); |
|
726 acceptError = KSVPErrTransferStateError; |
|
727 } |
|
728 |
|
729 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
730 OUT acceptError = %d", acceptError); |
|
731 return acceptError; |
|
732 } |
|
733 |
|
734 // --------------------------------------------------------------------------- |
|
735 // CSVPTransferController::TransferTarget |
|
736 // --------------------------------------------------------------------------- |
|
737 // |
|
738 const TDesC& CSVPTransferController::TransferTarget() const |
|
739 { |
|
740 return iTransferContext->IncomingReferTo(); |
|
741 } |
|
742 |
|
743 // --------------------------------------------------------------------------- |
|
744 // CSVPTransferController::AddObserverL |
|
745 // --------------------------------------------------------------------------- |
|
746 // |
|
747 void CSVPTransferController::AddObserverL( |
|
748 const MCCPTransferObserver& aObserver ) |
|
749 { |
|
750 SVPDEBUG1("CSVPTransferController::AddObserverL() In"); |
|
751 // set transfer observer |
|
752 // only one observer used at a time, replaces current one |
|
753 iCCPTransferObserver = const_cast<MCCPTransferObserver*>(&aObserver); |
|
754 |
|
755 SVPDEBUG1("CSVPTransferController::AddObserverL() Out"); |
|
756 } |
|
757 |
|
758 // --------------------------------------------------------------------------- |
|
759 // CSVPTransferController::RemoveObserver |
|
760 // --------------------------------------------------------------------------- |
|
761 // |
|
762 TInt CSVPTransferController::RemoveObserver( |
|
763 const MCCPTransferObserver& aObserver ) |
|
764 { |
|
765 SVPDEBUG1("CSVPTransferController::RemoveObserver"); |
|
766 TInt err = KErrNone; |
|
767 if ( iCCPTransferObserver == const_cast<MCCPTransferObserver*> |
|
768 (&aObserver) ) |
|
769 { |
|
770 iCCPTransferObserver = NULL; |
|
771 } |
|
772 else |
|
773 { |
|
774 err = KErrNotFound; |
|
775 } |
|
776 return err; |
|
777 } |
|
778 |
|
779 // --------------------------------------------------------------------------- |
|
780 // CSVPTransferController::TransferL |
|
781 // --------------------------------------------------------------------------- |
|
782 // |
|
783 void CSVPTransferController::TransferL( MCCPCall* aCall, |
|
784 const TDesC& aTarget, |
|
785 const TBool aAttendedTransfer ) |
|
786 { |
|
787 SVPDEBUG1("CSVPTransferController::TransferL() In"); |
|
788 |
|
789 // Transfer possible. |
|
790 if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() ) |
|
791 { |
|
792 iAccepted = EFalse; |
|
793 |
|
794 // Set transfer parameters |
|
795 iTransferContext->SetTransferParmsL( |
|
796 static_cast< CSVPSessionBase* >(aCall), |
|
797 aTarget, |
|
798 aAttendedTransfer ); |
|
799 |
|
800 // Apply state, execute the refer and change to next state (pending). |
|
801 iTransferContext->ApplyCurrentStateL(); |
|
802 } |
|
803 else |
|
804 { |
|
805 SVPDEBUG1( "CSVPTransferController::TransferL: Error - transfer in progress" ); |
|
806 iTransferContext->TransferObserver().TransferFailed( KErrInUse ); |
|
807 TerminateTransferL(); |
|
808 } |
|
809 |
|
810 SVPDEBUG1("CSVPTransferController::TransferL() OUT"); |
|
811 } |
|
812 |
|
813 |
|