|
1 /* |
|
2 * Copyright (c) 2006 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 { |
|
230 if ( iTransferContext->IsAttended() ) |
|
231 { |
|
232 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Attended case:\ |
|
233 SIP/2.0 200 OK" ); |
|
234 |
|
235 // Attended transfer (F24) 200 OK |
|
236 if( iCCPTransferObserver ) |
|
237 { |
|
238 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" ); |
|
239 iCCPTransferObserver->TransferEventOccurred( |
|
240 MCCPTransferObserver::ECCPLocalTransfer ); |
|
241 } |
|
242 |
|
243 // Set and apply the next state - terminating |
|
244 iTransferContext->SetCurrentStateL( |
|
245 KSVPTransferTerminatingStateIndex ); |
|
246 iTransferContext->ApplyCurrentStateL(); |
|
247 |
|
248 // Attended transfer is ok, hangup the session |
|
249 iTransferContext->TransferObserver().TransferNotification( |
|
250 ESVPTransferOKHangUp ); |
|
251 } |
|
252 else |
|
253 { |
|
254 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended: SIP/2.0 200 OK" ); |
|
255 } |
|
256 } |
|
257 else if ( !content->Find( TPtrC8( KSVPNotifyRinging ) ) && |
|
258 !iTransferContext->IsAttended()) |
|
259 { |
|
260 // Polycom send Ringing instead of Trying in unattended case. |
|
261 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, UnAttended and 180 Ringing" ); |
|
262 |
|
263 // Check if 202 Accepted already received |
|
264 if ( iAccepted ) |
|
265 { |
|
266 // Stop the refer timer |
|
267 iTransferContext->StopReferTimer( ); |
|
268 |
|
269 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, Unattended: Polycom case" ); |
|
270 |
|
271 // Unattended transfer: display "transferred" note |
|
272 if( iCCPTransferObserver ) |
|
273 { |
|
274 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, send local transfer" ); |
|
275 iCCPTransferObserver->TransferEventOccurred( |
|
276 MCCPTransferObserver::ECCPLocalTransfer ); |
|
277 } |
|
278 |
|
279 // Set and apply the next state - accepted |
|
280 iTransferContext->SetCurrentStateL( |
|
281 KSVPTransferAcceptedStateIndex ); |
|
282 iTransferContext->ApplyCurrentStateL(); |
|
283 |
|
284 iTransferContext->SetCurrentStateL( |
|
285 KSVPTransferTerminatingStateIndex ); |
|
286 iTransferContext->ApplyCurrentStateL(); |
|
287 // Unattended transfer is ok, hangup the session |
|
288 iTransferContext->TransferObserver().TransferNotification( |
|
289 ESVPTransferOKHangUp ); |
|
290 } |
|
291 } |
|
292 else if ( !content->Find( TPtrC8( KSVPNotifyServiceUnavailable ) ) ) |
|
293 { |
|
294 // Notify that comes after the accepted refer, if |
|
295 // the (wrong) address of the refer cannot be reached. |
|
296 if ( KSVPTransferAcceptedStateIndex == iTransferContext->CurrentState() ) |
|
297 { |
|
298 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503 -> ECCPTransferFailed"); |
|
299 |
|
300 // Set and apply the next state - terminating |
|
301 iTransferContext->SetCurrentStateL( |
|
302 KSVPTransferTerminatingStateIndex ); |
|
303 iTransferContext->ApplyCurrentStateL(); |
|
304 |
|
305 // Transfer fails, notify client. |
|
306 iTransferContext->TransferObserver().TransferNotification( |
|
307 ESVPTransferDecline ); |
|
308 } |
|
309 else |
|
310 { |
|
311 SVPDEBUG1( "CSVPTransferController::NotifyReceivedL, 503."); |
|
312 } |
|
313 } |
|
314 else |
|
315 { |
|
316 SVPDEBUG1("CSVPTransferController::NotifyReceivedL:\ |
|
317 Unhandled container content"); |
|
318 } |
|
319 |
|
320 // Ownership transferred here |
|
321 delete content; |
|
322 } |
|
323 |
|
324 SVPDEBUG1("CSVPTransferController::NotifyReceivedL: Out"); |
|
325 } |
|
326 |
|
327 |
|
328 // --------------------------------------------------------------------------- |
|
329 // CSVPTransferController::HandleReferStateChangeL |
|
330 // --------------------------------------------------------------------------- |
|
331 // |
|
332 void CSVPTransferController::HandleReferStateChangeL( CMceRefer& aRefer, |
|
333 TInt aStatusCode ) |
|
334 { |
|
335 SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() In"); |
|
336 |
|
337 if ( iTransferContext->MceRefer() == &aRefer ) |
|
338 { |
|
339 if ( KSVPAcceptedVal == aStatusCode ) |
|
340 { |
|
341 // Accepted unattended F6, Attended F16 |
|
342 SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Accept: %i", |
|
343 KSVPAcceptedVal ); |
|
344 |
|
345 // Display "transferring" note |
|
346 if( iCCPTransferObserver ) |
|
347 { |
|
348 SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL, send remote transferring" ); |
|
349 iCCPTransferObserver->TransferEventOccurred( |
|
350 MCCPTransferObserver::ECCPRemoteTransferring ); |
|
351 } |
|
352 // Continue acceptance when also notify F7 / F17 "trying" received |
|
353 iAccepted = ETrue; |
|
354 } |
|
355 else if ( ( KSVPBadRequestVal <= aStatusCode && |
|
356 KSVPRequestPendingVal >= aStatusCode ) || |
|
357 KSVPDeclineVal == aStatusCode || |
|
358 KSVPServerInternalErrorVal == aStatusCode || |
|
359 KSVPPreconditionFailureVal == aStatusCode ) |
|
360 { |
|
361 // Decline, Request Failure 4xx or Server Failure 5xx |
|
362 SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: Code: %i", aStatusCode ); |
|
363 // Stop the refer timer |
|
364 iTransferContext->StopReferTimer( ); |
|
365 |
|
366 // Set and apply the next state - terminating |
|
367 iTransferContext->SetCurrentStateL( |
|
368 KSVPTransferTerminatingStateIndex ); |
|
369 iTransferContext->ApplyCurrentStateL(); |
|
370 |
|
371 // Notify the observer about the decline. |
|
372 iTransferContext->TransferObserver().TransferNotification( |
|
373 ESVPTransferDecline ); |
|
374 } |
|
375 |
|
376 else |
|
377 { |
|
378 // Not handled |
|
379 SVPDEBUG2( "CSVPTransferController::HandleReferStateChangeL: \ |
|
380 Unknown StatusCode: %i", aStatusCode ); |
|
381 } |
|
382 } |
|
383 else |
|
384 { |
|
385 // Unknown refer - not handled |
|
386 SVPDEBUG1( "CSVPTransferController::HandleReferStateChangeL: \ |
|
387 Unknown refer"); |
|
388 } |
|
389 |
|
390 SVPDEBUG1("CSVPTransferController::HandleReferStateChangeL() Out"); |
|
391 } |
|
392 |
|
393 |
|
394 // --------------------------------------------------------------------------- |
|
395 // CSVPTransferController::IncomingReferL |
|
396 // --------------------------------------------------------------------------- |
|
397 // |
|
398 void CSVPTransferController::IncomingReferL( CMceInRefer* aRefer, |
|
399 const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer ) |
|
400 { |
|
401 SVPDEBUG1( "CSVPTransferController::IncomingReferL In" ) |
|
402 |
|
403 // Is new incoming refer handling possible |
|
404 if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() ) |
|
405 { |
|
406 SVPDEBUG1( "CSVPTransferController::IncomingReferL: allowed" ) |
|
407 |
|
408 iTransferContext->SetMceRefer( static_cast<CMceRefer*>( aRefer ) ); |
|
409 iTransferContext->SetIncomingReferToL( aReferTo ); |
|
410 CDesC8Array* headers = aContainer->GetHeaders();// get headers |
|
411 |
|
412 if ( headers ) |
|
413 { |
|
414 TBool found = EFalse; |
|
415 |
|
416 for( TInt i = 0; i < headers->MdcaCount() && !found; i++ ) |
|
417 { |
|
418 TPtrC8 tmpHeader = headers->MdcaPoint( i ); |
|
419 |
|
420 if ( KErrNotFound != tmpHeader.FindF( KSVPReferredBy ) ) |
|
421 { |
|
422 SVPDEBUG1( "KSVPReferredBy found" ) |
|
423 found = ETrue; |
|
424 iTransferContext->SetIncomingReferredByL( tmpHeader ); |
|
425 } |
|
426 } |
|
427 } |
|
428 |
|
429 delete headers; |
|
430 headers = NULL; |
|
431 } |
|
432 else |
|
433 { |
|
434 SVPDEBUG1( "CSVPTransferController::IncomingReferL: not allowed" ) |
|
435 User::Leave( KSVPErrTransferStateError ); |
|
436 } |
|
437 |
|
438 if ( iTransferContext->IsAttended() ) |
|
439 { |
|
440 SVPDEBUG1( "CSVPTransferController::IncomingReferL: Attended case, send accept" ) |
|
441 |
|
442 // send trying notification and wait respond for it |
|
443 CMceInEvent* inEvent = NULL; |
|
444 |
|
445 TRAPD( acceptError, inEvent = static_cast<CMceInRefer*>( |
|
446 iTransferContext->MceRefer() )->AcceptL() ); |
|
447 |
|
448 if ( KErrNone == acceptError ) |
|
449 { |
|
450 // Apply state, changes to next state (pending) |
|
451 SVPDEBUG1( "CSVPTransferController::IncomingReferL: pending state" ) |
|
452 iTransferContext->SetMceEvent( static_cast<CMceEvent*>( inEvent ) ); |
|
453 iTransferContext->ApplyCurrentStateL(); |
|
454 } |
|
455 else |
|
456 { |
|
457 // Set and apply the next state - terminating |
|
458 SVPDEBUG2("CSVPTransferController::IncomingReferL: acc fails = %d", acceptError ) |
|
459 iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex ); |
|
460 iTransferContext->ApplyCurrentStateL(); |
|
461 } |
|
462 } |
|
463 else |
|
464 { |
|
465 // Apply state, changes to next state (pending) |
|
466 SVPDEBUG1( "CSVPTransferController::IncomingReferL: UnAttended case pending" ) |
|
467 iTransferContext->ApplyCurrentStateL(); |
|
468 } |
|
469 |
|
470 SVPDEBUG1( "CSVPTransferController::IncomingReferL Out" ) |
|
471 } |
|
472 |
|
473 // --------------------------------------------------------------------------- |
|
474 // CSVPTransferController::IsMceRefer |
|
475 // --------------------------------------------------------------------------- |
|
476 // |
|
477 TBool CSVPTransferController::IsMceRefer( CMceRefer& aRefer ) |
|
478 { |
|
479 return ( iTransferContext->MceRefer() == &aRefer ); |
|
480 } |
|
481 |
|
482 // --------------------------------------------------------------------------- |
|
483 // CSVPTransferController::IsAttended |
|
484 // --------------------------------------------------------------------------- |
|
485 // |
|
486 TBool CSVPTransferController::IsAttended( ) |
|
487 { |
|
488 return ( iTransferContext->IsAttended() ); |
|
489 } |
|
490 |
|
491 // --------------------------------------------------------------------------- |
|
492 // CSVPTransferController::SetTransferDataL |
|
493 // --------------------------------------------------------------------------- |
|
494 // |
|
495 void CSVPTransferController::SetTransferDataL( CDesC8Array* aUserAgentHeaders, |
|
496 TInt aSecureStatus ) |
|
497 { |
|
498 SVPDEBUG1(" CSVPTransferController::SetTransferDataL" ); |
|
499 iTransferContext->SetTransferDataL( aUserAgentHeaders, aSecureStatus ); |
|
500 } |
|
501 |
|
502 // --------------------------------------------------------------------------- |
|
503 // CSVPTransferController::SetMceSessionObject |
|
504 // --------------------------------------------------------------------------- |
|
505 // |
|
506 void CSVPTransferController::SetMceSessionObject( CMceSession* aSession ) |
|
507 { |
|
508 iTransferContext->SetMceSessionObject( aSession ); |
|
509 } |
|
510 |
|
511 // --------------------------------------------------------------------------- |
|
512 // CSVPTransferController::SendNotifyL |
|
513 // --------------------------------------------------------------------------- |
|
514 // |
|
515 void CSVPTransferController::SendNotifyL( TInt aStatusCode ) |
|
516 { |
|
517 SVPDEBUG2("CSVPTransferController::SendNotifyL() code = %d", aStatusCode); |
|
518 |
|
519 CMceInEvent* inEvent = static_cast< CMceInEvent* > ( |
|
520 iTransferContext->MceEvent()); |
|
521 if (inEvent) |
|
522 { |
|
523 HBufC8* contentType = KSVPMessageSipfrag().AllocLC(); //message/sipfrag |
|
524 HBufC8* content = NULL; |
|
525 |
|
526 if (KSVPOKVal == aStatusCode ) |
|
527 { |
|
528 content = KSVPNotifyOK().AllocLC(); // "SIP/2.0 200 OK" |
|
529 } |
|
530 else if ( KSVPNotFoundVal == aStatusCode || |
|
531 KSVPBusyHereVal == aStatusCode || |
|
532 KSVPDeclineVal == aStatusCode ) |
|
533 { |
|
534 content = KSVPNotifyServiceUnavailable().AllocLC(); // "503" |
|
535 } |
|
536 else |
|
537 { |
|
538 SVPDEBUG2("CSVPTransferController::SendNotifyL unknown aStatusCode = %d", aStatusCode); |
|
539 content = KSVPNotifyServiceUnavailable().AllocLC(); // "503" |
|
540 } |
|
541 |
|
542 CDesC8Array* headers = NULL; |
|
543 headers = new( ELeave ) CDesC8ArrayFlat( KSVPContactArrayGranularity ); |
|
544 CleanupStack::PushL( headers ); |
|
545 headers->AppendL( KSVPSubsStateTerminated ); |
|
546 |
|
547 // Notify is sent to transferer (unattended msg F15, attended msg F24) |
|
548 TRAPD( errNotify, inEvent->TerminateL( headers, contentType, content ) ); |
|
549 |
|
550 if ( KErrNone == errNotify ) |
|
551 { |
|
552 SVPDEBUG1("CSVPTransferController::SendNotifyL, notify sending OK"); |
|
553 CleanupStack::Pop( 3, contentType ); // headers, content, contentType |
|
554 } |
|
555 else |
|
556 { |
|
557 // error handling |
|
558 SVPDEBUG2("CSVPTransferController::SendNotifyL: errNotify = %d", errNotify ); |
|
559 CleanupStack::PopAndDestroy( 3, contentType ); // headers, content, contentType |
|
560 } |
|
561 } |
|
562 |
|
563 if ( iTransferContext->IsAttended() ) |
|
564 { |
|
565 SVPDEBUG1("CSVPTransferController::SendNotifyL() Attended done"); |
|
566 } |
|
567 else |
|
568 { |
|
569 SVPDEBUG1("CSVPTransferController::SendNotifyL() UnAttended to terminating state"); |
|
570 // Finish unattended incoming transfer sequence |
|
571 // Set and apply the next state - terminating |
|
572 iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex ); |
|
573 iTransferContext->ApplyCurrentStateL(); |
|
574 } |
|
575 |
|
576 SVPDEBUG1("CSVPTransferController::SendNotifyL() Out"); |
|
577 } |
|
578 |
|
579 // --------------------------------------------------------------------------- |
|
580 // CSVPTransferController::IsIncomingTransfer |
|
581 // --------------------------------------------------------------------------- |
|
582 // |
|
583 TBool CSVPTransferController::IsIncomingTransfer() |
|
584 { |
|
585 SVPDEBUG2("CSVPTransferController::IsIncomingTransfer = %d", |
|
586 iTransferContext->IsIncoming() ); |
|
587 return iTransferContext->IsIncoming(); |
|
588 } |
|
589 |
|
590 // --------------------------------------------------------------------------- |
|
591 // CSVPTransferController::TerminateTransfer |
|
592 // --------------------------------------------------------------------------- |
|
593 // |
|
594 void CSVPTransferController::TerminateTransfer() |
|
595 { |
|
596 SVPDEBUG1("CSVPTransferController::TerminateTransfer" ) |
|
597 TRAP_IGNORE( TerminateTransferL() ); |
|
598 } |
|
599 |
|
600 // --------------------------------------------------------------------------- |
|
601 // CSVPTransferController::TerminateTransferL |
|
602 // --------------------------------------------------------------------------- |
|
603 // |
|
604 void CSVPTransferController::TerminateTransferL() |
|
605 { |
|
606 iTransferContext->SetCurrentStateL( KSVPTransferTerminatingStateIndex ); |
|
607 iTransferContext->ApplyCurrentStateL(); |
|
608 } |
|
609 |
|
610 // --------------------------------------------------------------------------- |
|
611 // CSVPTransferController::AttendedTransfer |
|
612 // --------------------------------------------------------------------------- |
|
613 // |
|
614 TInt CSVPTransferController::AttendedTransfer( MCCPCall& aTransferTargetCall ) |
|
615 { |
|
616 SVPDEBUG1( "CSVPTransferController::AttendedTransfer call IN" ); |
|
617 TRAPD( transError, TransferL( &aTransferTargetCall, KNullDesC, ETrue )); |
|
618 SVPDEBUG2( "CSVPTransferController::AttendedTransfer A return: %d", transError ); |
|
619 return transError; |
|
620 } |
|
621 |
|
622 // --------------------------------------------------------------------------- |
|
623 // CSVPTransferController::AttendedTransfer |
|
624 // --------------------------------------------------------------------------- |
|
625 // |
|
626 TInt CSVPTransferController::AttendedTransfer( const TDesC& aTransferTarget ) |
|
627 { |
|
628 SVPDEBUG1( "CSVPTransferController::AttendedTransfer target IN" ); |
|
629 TRAPD( transError, TransferL( NULL, aTransferTarget, ETrue )); |
|
630 SVPDEBUG2( "CSVPTransferController::AttendedTransfer B return: %d", transError ); |
|
631 return transError; |
|
632 } |
|
633 |
|
634 // --------------------------------------------------------------------------- |
|
635 // CSVPTransferController::UnattendedTransfer |
|
636 // --------------------------------------------------------------------------- |
|
637 // |
|
638 TInt CSVPTransferController::UnattendedTransfer( const TDesC& aTransferTarget ) |
|
639 { |
|
640 SVPDEBUG1( "CSVPTransferController::UnattendedTransfer IN" ); |
|
641 TRAPD( transError, TransferL( NULL, aTransferTarget, EFalse )); |
|
642 SVPDEBUG2( "CSVPTransferController::UnattendedTransfer return: %d", transError ); |
|
643 return transError; |
|
644 } |
|
645 |
|
646 // --------------------------------------------------------------------------- |
|
647 // CSVPTransferController::AcceptTransfer |
|
648 // --------------------------------------------------------------------------- |
|
649 // |
|
650 TInt CSVPTransferController::AcceptTransfer( const TBool aAccept ) |
|
651 { |
|
652 SVPDEBUG2("CSVPTransferController::AcceptTransfer() IN aAccept = \ |
|
653 %d", aAccept); |
|
654 TInt acceptError = KErrNone; |
|
655 TInt stateError = KErrNone; |
|
656 TInt currentState = iTransferContext->CurrentState(); |
|
657 CMceInEvent* inEvent(NULL); |
|
658 |
|
659 // Is state "pending" |
|
660 if ( KSVPTransferPendingStateIndex == currentState ) |
|
661 { |
|
662 if ( aAccept ) |
|
663 { |
|
664 TRAP( acceptError, ( inEvent = static_cast< CMceInRefer* > (iTransferContext->MceRefer())->AcceptL())); |
|
665 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
666 AcceptL = %d", acceptError); |
|
667 } |
|
668 else |
|
669 { |
|
670 SVPDEBUG1("CSVPTransferController::AcceptTransfer() reject"); |
|
671 TRAP( acceptError, ( static_cast< CMceInRefer* > (iTransferContext->MceRefer())->RejectL()) ); |
|
672 } |
|
673 |
|
674 if ( KErrNone == acceptError ) |
|
675 { |
|
676 if ( aAccept ) |
|
677 { |
|
678 // Set the received event |
|
679 iTransferContext->SetMceEvent(static_cast< CMceEvent* >(inEvent)); |
|
680 |
|
681 // Set and apply the next state - accepted |
|
682 TRAP( acceptError, |
|
683 iTransferContext->SetCurrentStateL( |
|
684 KSVPTransferAcceptedStateIndex ); |
|
685 iTransferContext->ApplyCurrentStateL(); |
|
686 ); |
|
687 } |
|
688 else |
|
689 { |
|
690 // Set and apply the next state - terminating |
|
691 TRAP( acceptError, |
|
692 iTransferContext->SetCurrentStateL( |
|
693 KSVPTransferTerminatingStateIndex ); |
|
694 iTransferContext->ApplyCurrentStateL(); |
|
695 ); |
|
696 } |
|
697 } |
|
698 else |
|
699 { |
|
700 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
701 fails = %d", acceptError); |
|
702 // Set and apply the next state - terminating |
|
703 TRAP( stateError, |
|
704 iTransferContext->SetCurrentStateL( |
|
705 KSVPTransferTerminatingStateIndex ); |
|
706 iTransferContext->ApplyCurrentStateL(); |
|
707 ); |
|
708 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
709 stateError = %d", stateError); |
|
710 } |
|
711 } |
|
712 else |
|
713 { |
|
714 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
715 current state is not pending: %d", currentState); |
|
716 acceptError = KSVPErrTransferStateError; |
|
717 } |
|
718 |
|
719 SVPDEBUG2("CSVPTransferController::AcceptTransfer()\ |
|
720 OUT acceptError = %d", acceptError); |
|
721 return acceptError; |
|
722 } |
|
723 |
|
724 // --------------------------------------------------------------------------- |
|
725 // CSVPTransferController::TransferTarget |
|
726 // --------------------------------------------------------------------------- |
|
727 // |
|
728 const TDesC& CSVPTransferController::TransferTarget() const |
|
729 { |
|
730 return iTransferContext->IncomingReferTo(); |
|
731 } |
|
732 |
|
733 // --------------------------------------------------------------------------- |
|
734 // CSVPTransferController::AddObserverL |
|
735 // --------------------------------------------------------------------------- |
|
736 // |
|
737 void CSVPTransferController::AddObserverL( |
|
738 const MCCPTransferObserver& aObserver ) |
|
739 { |
|
740 SVPDEBUG1("CSVPTransferController::AddObserverL() In"); |
|
741 // set transfer observer |
|
742 // only one observer used at a time, replaces current one |
|
743 iCCPTransferObserver = const_cast<MCCPTransferObserver*>(&aObserver); |
|
744 |
|
745 SVPDEBUG1("CSVPTransferController::AddObserverL() Out"); |
|
746 } |
|
747 |
|
748 // --------------------------------------------------------------------------- |
|
749 // CSVPTransferController::RemoveObserver |
|
750 // --------------------------------------------------------------------------- |
|
751 // |
|
752 TInt CSVPTransferController::RemoveObserver( |
|
753 const MCCPTransferObserver& aObserver ) |
|
754 { |
|
755 SVPDEBUG1("CSVPTransferController::RemoveObserver"); |
|
756 TInt err = KErrNone; |
|
757 if ( iCCPTransferObserver == const_cast<MCCPTransferObserver*> |
|
758 (&aObserver) ) |
|
759 { |
|
760 iCCPTransferObserver = NULL; |
|
761 } |
|
762 else |
|
763 { |
|
764 err = KErrNotFound; |
|
765 } |
|
766 return err; |
|
767 } |
|
768 |
|
769 // --------------------------------------------------------------------------- |
|
770 // CSVPTransferController::TransferL |
|
771 // --------------------------------------------------------------------------- |
|
772 // |
|
773 void CSVPTransferController::TransferL( MCCPCall* aCall, |
|
774 const TDesC& aTarget, |
|
775 const TBool aAttendedTransfer ) |
|
776 { |
|
777 SVPDEBUG1("CSVPTransferController::TransferL() In"); |
|
778 |
|
779 // Transfer possible. |
|
780 if ( KSVPTransferIdleStateIndex == iTransferContext->CurrentState() ) |
|
781 { |
|
782 iAccepted = EFalse; |
|
783 |
|
784 // Set transfer parameters |
|
785 iTransferContext->SetTransferParmsL( |
|
786 static_cast< CSVPSessionBase* >(aCall), |
|
787 aTarget, |
|
788 aAttendedTransfer ); |
|
789 |
|
790 // Apply state, execute the refer and change to next state (pending). |
|
791 iTransferContext->ApplyCurrentStateL(); |
|
792 } |
|
793 else |
|
794 { |
|
795 SVPDEBUG1( "CSVPTransferController::TransferL: Error - transfer in progress" ); |
|
796 iTransferContext->TransferObserver().TransferFailed( KErrInUse ); |
|
797 TerminateTransferL(); |
|
798 } |
|
799 |
|
800 SVPDEBUG1("CSVPTransferController::TransferL() OUT"); |
|
801 } |
|
802 |
|
803 |