|
1 /* |
|
2 * Copyright (c) 2009 Sony Ericsson Mobile Communications AB |
|
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 * Sony Ericsson Mobile Communications AB - initial contribution. |
|
11 * Nokia Corporation - additional changes. |
|
12 * |
|
13 * Contributors: |
|
14 * |
|
15 * Description: |
|
16 * Code for TelephonyFuncLine class, used by CTelephony class. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 /** |
|
22 @file |
|
23 */ |
|
24 |
|
25 #include <e32def.h> |
|
26 #include "TelephonyFunctions.h" |
|
27 #include "TelephonyActCall.h" |
|
28 #include "TelephonyActLine.h" |
|
29 |
|
30 TInt CTelephonyFunctions::DialNewCallL(TRequestStatus& aRequestStatus, TDes8& aCallParams, |
|
31 const CTelephony::TTelNumber& aTelNumber, CTelephony::TCallId& aCallId, const CTelephony::TPhoneLine aLine) |
|
32 /** |
|
33 Dial a new call. |
|
34 */ |
|
35 { |
|
36 TName myCallName; |
|
37 |
|
38 if(aLine != CTelephony::EVoiceLine) |
|
39 { |
|
40 return KErrAccessDenied; |
|
41 } |
|
42 |
|
43 if(IsRequestPending(CTelephonyFunctions::EDialNewCall)!=EFalse) |
|
44 { |
|
45 return KErrInUse; |
|
46 } |
|
47 else |
|
48 { |
|
49 SetRequestPending(CTelephonyFunctions::EDialNewCall, ETrue); |
|
50 } |
|
51 |
|
52 CTelephony::TCallId myCallId; |
|
53 if(GetISVCall(myCallId) != KErrNone) |
|
54 { |
|
55 return KErrAccessDenied; |
|
56 } |
|
57 |
|
58 if(!iDialNewCall) |
|
59 { |
|
60 iDialNewCall = CDialNewCallAct::NewL(this); |
|
61 } |
|
62 |
|
63 if(IsFlightModeOn()) |
|
64 { |
|
65 return KErrAccessDenied; |
|
66 } |
|
67 |
|
68 // 1. If call object has not been previously opened then call OpenNewCall. |
|
69 // 2. If the call object was previously opened and used for an AnswerIncomingCall we close the object and then call re-open it with OpenNewCall. |
|
70 // 3. If call object was previously opened and used for a dial then can re-use it. |
|
71 |
|
72 switch(iCallPoolStatus[myCallId]) |
|
73 { |
|
74 case EAnswer: |
|
75 CloseAndReset(myCallId); |
|
76 case EUnset: |
|
77 User::LeaveIfError(iCallPool[myCallId].OpenNewCall(iLineVoice, myCallName)); |
|
78 break; |
|
79 case EDial: |
|
80 default: |
|
81 break; |
|
82 } |
|
83 iCallPoolStatus[myCallId]=EDial; |
|
84 |
|
85 iReqStatusTable[EDialNewCall] = &aRequestStatus; |
|
86 |
|
87 iDialNewCall->DialNewCall(aCallParams,aTelNumber,aCallId,myCallId); |
|
88 |
|
89 return KErrNone; |
|
90 } |
|
91 |
|
92 TInt CTelephonyFunctions::HoldL(TRequestStatus& aRequestStatus, const CTelephony::TCallId& aCallId) |
|
93 /** |
|
94 Attempt to place a call on hold. |
|
95 */ |
|
96 { |
|
97 if((aCallId != CTelephony::EISVCall1) && |
|
98 (aCallId != CTelephony::EISVCall2)) |
|
99 { |
|
100 return KErrAccessDenied; |
|
101 } |
|
102 |
|
103 if(IsRequestPending(CTelephonyFunctions::EHold)!=EFalse) |
|
104 { |
|
105 return KErrInUse; |
|
106 } |
|
107 else |
|
108 { |
|
109 SetRequestPending(CTelephonyFunctions::EHold, ETrue); |
|
110 } |
|
111 |
|
112 if(IsFlightModeOn()) |
|
113 { |
|
114 return KErrAccessDenied; |
|
115 } |
|
116 |
|
117 RMobileCall::TMobileCallStatus callStatus; |
|
118 if(Call(aCallId)!=NULL) |
|
119 { |
|
120 Call(aCallId)->GetMobileCallStatus(callStatus); |
|
121 if(callStatus!=RMobileCall::EStatusConnected) |
|
122 return KErrAccessDenied; |
|
123 } |
|
124 else |
|
125 { |
|
126 return KErrAccessDenied; |
|
127 } |
|
128 |
|
129 if(!iHold) |
|
130 { |
|
131 iHold = CHoldAct::NewL(this); |
|
132 } |
|
133 |
|
134 iReqStatusTable[EHold] = &aRequestStatus; |
|
135 |
|
136 iHold->Hold(aCallId); |
|
137 |
|
138 return KErrNone; |
|
139 } |
|
140 |
|
141 TInt CTelephonyFunctions::ResumeL(TRequestStatus& aRequestStatus, const CTelephony::TCallId& aCallId) |
|
142 /** |
|
143 Attempt to Resume a previously held call |
|
144 */ |
|
145 { |
|
146 if((aCallId != CTelephony::EISVCall1) && |
|
147 (aCallId != CTelephony::EISVCall2)) |
|
148 { |
|
149 return KErrAccessDenied; |
|
150 } |
|
151 |
|
152 if(IsRequestPending(CTelephonyFunctions::EResume)!=EFalse) |
|
153 { |
|
154 return KErrInUse; |
|
155 } |
|
156 else |
|
157 { |
|
158 SetRequestPending(CTelephonyFunctions::EResume, ETrue); |
|
159 } |
|
160 |
|
161 if(IsFlightModeOn()) |
|
162 { |
|
163 return KErrAccessDenied; |
|
164 } |
|
165 |
|
166 RMobileCall::TMobileCallStatus callStatus; |
|
167 if(Call(aCallId)!=NULL) |
|
168 { |
|
169 Call(aCallId)->GetMobileCallStatus(callStatus); |
|
170 if(callStatus!=RMobileCall::EStatusHold) |
|
171 return KErrAccessDenied; |
|
172 } |
|
173 else |
|
174 { |
|
175 return KErrAccessDenied; |
|
176 } |
|
177 |
|
178 if(!iResume) |
|
179 { |
|
180 iResume = CResumeAct::NewL(this); |
|
181 } |
|
182 |
|
183 iReqStatusTable[EResume] = &aRequestStatus; |
|
184 |
|
185 iResume->Resume(aCallId); |
|
186 |
|
187 return KErrNone; |
|
188 } |
|
189 |
|
190 TInt CTelephonyFunctions::SwapL(TRequestStatus& aRequestStatus, const CTelephony::TCallId& aCallId1, const |
|
191 CTelephony::TCallId& aCallId2) |
|
192 /** |
|
193 Attempt to swap the currently held and active calls. |
|
194 */ |
|
195 { |
|
196 |
|
197 if(!((aCallId1 == CTelephony::EISVCall1 && |
|
198 aCallId2 == CTelephony::EISVCall2) || |
|
199 (aCallId1 == CTelephony::EISVCall2 && |
|
200 aCallId2 == CTelephony::EISVCall1) |
|
201 )) |
|
202 { |
|
203 return KErrAccessDenied; |
|
204 } |
|
205 |
|
206 if(IsRequestPending(CTelephonyFunctions::ESwap)!=EFalse) |
|
207 { |
|
208 return KErrInUse; |
|
209 } |
|
210 else |
|
211 { |
|
212 SetRequestPending(CTelephonyFunctions::ESwap, ETrue); |
|
213 } |
|
214 |
|
215 if(IsFlightModeOn()) |
|
216 { |
|
217 return KErrAccessDenied; |
|
218 } |
|
219 |
|
220 RMobileCall::TMobileCallStatus callStatus1, callStatus2; |
|
221 if((Call(aCallId1)!=NULL) && (Call(aCallId2)!=NULL)) |
|
222 { |
|
223 Call(aCallId1)->GetMobileCallStatus(callStatus1); |
|
224 Call(aCallId2)->GetMobileCallStatus(callStatus2); |
|
225 |
|
226 if (!( ((callStatus1==RMobileCall::EStatusConnected) && |
|
227 (callStatus2==RMobileCall::EStatusHold)) || |
|
228 ((callStatus1==RMobileCall::EStatusHold) && |
|
229 (callStatus2==RMobileCall::EStatusConnected)))) |
|
230 { |
|
231 return KErrAccessDenied; |
|
232 } |
|
233 } |
|
234 else |
|
235 { |
|
236 return KErrAccessDenied; |
|
237 } |
|
238 |
|
239 if(!iSwap) |
|
240 { |
|
241 iSwap = CSwapAct::NewL(this); |
|
242 } |
|
243 |
|
244 iReqStatusTable[ESwap] = &aRequestStatus; |
|
245 |
|
246 iSwap->Swap(aCallId1); |
|
247 |
|
248 return KErrNone; |
|
249 } |
|
250 |
|
251 TInt CTelephonyFunctions::HangupL(TRequestStatus& aRequestStatus, const CTelephony::TCallId& aCallId) |
|
252 /** |
|
253 Attempt to hangup a call. |
|
254 */ |
|
255 { |
|
256 if((aCallId != CTelephony::EISVCall1) && |
|
257 (aCallId != CTelephony::EISVCall2)) |
|
258 { |
|
259 return KErrAccessDenied; |
|
260 } |
|
261 |
|
262 if(IsRequestPending(CTelephonyFunctions::EHangup)!=EFalse) |
|
263 { |
|
264 return KErrInUse; |
|
265 } |
|
266 else |
|
267 { |
|
268 SetRequestPending(CTelephonyFunctions::EHangup, ETrue); |
|
269 } |
|
270 |
|
271 if(IsFlightModeOn()) |
|
272 { |
|
273 return KErrAccessDenied; |
|
274 } |
|
275 |
|
276 RMobileCall::TMobileCallStatus callStatus; |
|
277 if(Call(aCallId)!=NULL) |
|
278 { |
|
279 Call(aCallId)->GetMobileCallStatus(callStatus); |
|
280 if(callStatus!=RMobileCall::EStatusHold && |
|
281 callStatus!=RMobileCall::EStatusConnected && |
|
282 callStatus!=RMobileCall::EStatusConnecting && |
|
283 callStatus!=RMobileCall::EStatusRinging && |
|
284 callStatus!=RMobileCall::EStatusAnswering) |
|
285 { |
|
286 return KErrAccessDenied; |
|
287 } |
|
288 } |
|
289 else |
|
290 { |
|
291 return KErrAccessDenied; |
|
292 } |
|
293 |
|
294 if(!iHangup) |
|
295 { |
|
296 iHangup = CHangupAct::NewL(this); |
|
297 } |
|
298 |
|
299 iReqStatusTable[EHangup] = &aRequestStatus; |
|
300 |
|
301 iHangup->Hangup(aCallId); |
|
302 |
|
303 return KErrNone; |
|
304 } |
|
305 |
|
306 /** |
|
307 Attempt to answer an incoming call. |
|
308 |
|
309 This can only be done with a voice line. |
|
310 */ |
|
311 TInt CTelephonyFunctions::AnswerIncomingCallL(TRequestStatus& aRequestStatus, CTelephony::TCallId& aCallId, |
|
312 const CTelephony::TPhoneLine aLine) |
|
313 { |
|
314 if(aLine != CTelephony::EVoiceLine) |
|
315 { |
|
316 return KErrAccessDenied; |
|
317 } |
|
318 |
|
319 if(IsRequestPending(CTelephonyFunctions::EAnswerIncomingCall)!=EFalse) |
|
320 { |
|
321 return KErrInUse; |
|
322 } |
|
323 else |
|
324 { |
|
325 SetRequestPending(CTelephonyFunctions::EAnswerIncomingCall, ETrue); |
|
326 } |
|
327 |
|
328 // Get free call line. If none available then return. |
|
329 CTelephony::TCallId myCallId; |
|
330 if(GetISVCall(myCallId) != KErrNone) |
|
331 { |
|
332 return KErrAccessDenied; |
|
333 } |
|
334 |
|
335 if(IsFlightModeOn()) |
|
336 { |
|
337 return KErrAccessDenied; |
|
338 } |
|
339 |
|
340 RMobileCall::TMobileCallStatus callStatus; |
|
341 |
|
342 // Check that the line is in the ringing state. |
|
343 // If it is not then there is no call to answer |
|
344 // so return. |
|
345 User::LeaveIfError(iLineVoice.GetMobileLineStatus(callStatus)); |
|
346 if(callStatus!=RMobileCall::EStatusRinging) |
|
347 { |
|
348 return KErrAccessDenied; |
|
349 } |
|
350 |
|
351 // Our call pool object (returned from GetISVCall() above) may |
|
352 // have been previously used. |
|
353 // This means a OpenExistingCall or OpenNewCall has been called |
|
354 // previously which must be closed before we call |
|
355 // OpenExistingCall again. |
|
356 if(iCallPoolStatus[myCallId]==EAnswer || iCallPoolStatus[myCallId]==EDial) |
|
357 { |
|
358 CloseAndReset(myCallId); |
|
359 } |
|
360 |
|
361 //Create an answer call AO. |
|
362 if(iAnswerIncomingCall == NULL) |
|
363 { |
|
364 iAnswerIncomingCall = CAnswerIncomingCallAct::NewL(this, *iInternalNotifyIncomingCall, iCallPool, iCallPoolStatus); |
|
365 } |
|
366 |
|
367 iReqStatusTable[EAnswerIncomingCall] = &aRequestStatus; |
|
368 |
|
369 // Initiate answer call request. |
|
370 iAnswerIncomingCall->AnswerIncomingCall(aCallId,myCallId); |
|
371 |
|
372 return KErrNone; |
|
373 } |
|
374 |
|
375 /** |
|
376 Retrieve the current call status. |
|
377 */ |
|
378 TInt CTelephonyFunctions::GetCallStatusL(const CTelephony::TCallId& aCallId, TDes8& aStatus) |
|
379 { |
|
380 if((aCallId != CTelephony::EISVCall1) && |
|
381 (aCallId != CTelephony::EISVCall2)) |
|
382 { |
|
383 return KErrAccessDenied; |
|
384 } |
|
385 |
|
386 CTelephony::TCallStatusV1& CallStatusV1 = |
|
387 reinterpret_cast<CTelephony::TCallStatusV1&> ( const_cast<TUint8&> ( *aStatus.Ptr() ) ); |
|
388 |
|
389 RMobileCall::TMobileCallStatus callStatus=RMobileCall::EStatusUnknown; |
|
390 |
|
391 if(Call(aCallId) == NULL) |
|
392 { |
|
393 return KErrAccessDenied; |
|
394 } |
|
395 |
|
396 if(IsFlightModeOn()) |
|
397 { |
|
398 return KErrAccessDenied; |
|
399 } |
|
400 |
|
401 User::LeaveIfError(Call(aCallId)->GetMobileCallStatus(callStatus)); |
|
402 |
|
403 GetCallStatus(callStatus, CallStatusV1.iStatus); |
|
404 |
|
405 return KErrNone; |
|
406 } |
|
407 |
|
408 void CTelephonyFunctions::GetCallStatus(const RMobileCall::TMobileCallStatus aMMCallStatus, CTelephony::TCallStatus& aTelCallStatus) |
|
409 /** |
|
410 Map RMobileCall::TMobileCallStatus to CTelephony::TCallStatus |
|
411 */ |
|
412 { |
|
413 switch(aMMCallStatus) |
|
414 { |
|
415 case RMobileCall::EStatusUnknown: |
|
416 aTelCallStatus=CTelephony::EStatusUnknown; |
|
417 break; |
|
418 case RMobileCall::EStatusIdle: |
|
419 aTelCallStatus=CTelephony::EStatusIdle; |
|
420 break; |
|
421 case RMobileCall::EStatusDialling: |
|
422 aTelCallStatus=CTelephony::EStatusDialling; |
|
423 break; |
|
424 case RMobileCall::EStatusRinging: |
|
425 aTelCallStatus=CTelephony::EStatusRinging; |
|
426 break; |
|
427 case RMobileCall::EStatusAnswering: |
|
428 aTelCallStatus=CTelephony::EStatusAnswering; |
|
429 break; |
|
430 case RMobileCall::EStatusConnecting: |
|
431 aTelCallStatus=CTelephony::EStatusConnecting; |
|
432 break; |
|
433 case RMobileCall::EStatusConnected: |
|
434 aTelCallStatus=CTelephony::EStatusConnected; |
|
435 break; |
|
436 case RMobileCall::EStatusReconnectPending: |
|
437 aTelCallStatus=CTelephony::EStatusReconnectPending; |
|
438 break; |
|
439 case RMobileCall::EStatusDisconnecting: |
|
440 aTelCallStatus=CTelephony::EStatusDisconnecting; |
|
441 break; |
|
442 case RMobileCall::EStatusHold: |
|
443 aTelCallStatus=CTelephony::EStatusHold; |
|
444 break; |
|
445 case RMobileCall::EStatusTransferring: |
|
446 aTelCallStatus=CTelephony::EStatusTransferring; |
|
447 break; |
|
448 case RMobileCall::EStatusTransferAlerting: |
|
449 aTelCallStatus=CTelephony::EStatusTransferAlerting; |
|
450 break; |
|
451 default: |
|
452 aTelCallStatus=CTelephony::EStatusUnknown; |
|
453 break; |
|
454 } |
|
455 } |
|
456 |
|
457 TInt CTelephonyFunctions::GetCallDynamicCaps(const CTelephony::TCallId& aCallId, TDes8& aCaps) |
|
458 /** |
|
459 Retrieve the calls dynamic capabilities. |
|
460 */ |
|
461 { |
|
462 if((aCallId != CTelephony::EISVCall1) && |
|
463 (aCallId != CTelephony::EISVCall2)) |
|
464 { |
|
465 return KErrAccessDenied; |
|
466 } |
|
467 |
|
468 CTelephony::TCallCapsV1& CallCapsV1 = *( reinterpret_cast<CTelephony::TCallCapsV1*> |
|
469 ( const_cast<TUint8*> ( aCaps.Ptr() ) ) ); |
|
470 RMobileCall::TMobileCallCapsV1 callCaps; |
|
471 RMobileCall::TMobileCallCapsV1Pckg callCapsPckg(callCaps); |
|
472 |
|
473 if(Call(aCallId)==NULL) |
|
474 { |
|
475 return KErrAccessDenied; |
|
476 } |
|
477 |
|
478 if(IsFlightModeOn()) |
|
479 { |
|
480 return KErrAccessDenied; |
|
481 } |
|
482 |
|
483 TInt ret = Call(aCallId)->GetMobileCallCaps(callCapsPckg); |
|
484 |
|
485 // Set the call control capability |
|
486 CallCapsV1.iControlCaps = 0; |
|
487 if (callCaps.iCallControlCaps & RMobileCall::KCapsHold) |
|
488 CallCapsV1.iControlCaps |= CTelephony::KCapsHold; |
|
489 if (callCaps.iCallControlCaps & RMobileCall::KCapsResume) |
|
490 CallCapsV1.iControlCaps |= CTelephony::KCapsResume; |
|
491 if (callCaps.iCallControlCaps & RMobileCall::KCapsSwap) |
|
492 CallCapsV1.iControlCaps |= CTelephony::KCapsSwap; |
|
493 |
|
494 return ret; |
|
495 } |
|
496 |
|
497 |