|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <commsdattypesv1_1.h> |
|
17 #include "CALL.H" // Header file for this source file |
|
18 #include "NOTIFY.H" |
|
19 #include "FAX.H" |
|
20 #include "ATDIAL.H" |
|
21 #include "ATANSWER.H" |
|
22 #include "ATCONNCT.H" |
|
23 #include "ATHANGUP.H" |
|
24 #include "ATO.H" |
|
25 #include "ATNOCARR.H" |
|
26 #include "LINE.H" |
|
27 #include "ATINIT.H" |
|
28 #include "mSLOGGER.H" // for LOGTEXT untilities |
|
29 #include "ATIO.H" // For CATIO class |
|
30 #include "PHONE.H" |
|
31 #include <et_clsvr.h> |
|
32 #include "ATBASE.H" |
|
33 #include "Matstd.h" // For AT command string constants |
|
34 #include "set_cbst.h" // for CATSetCBST class |
|
35 #include "et_struct.h" |
|
36 |
|
37 _LIT(KFaxServerName,"FaxSvr.dll"); |
|
38 |
|
39 |
|
40 // |
|
41 // CAcquireEntry class |
|
42 // |
|
43 CAcquireEntry* CAcquireEntry::NewL(const TTsyReqHandle aTsyReqHandle) |
|
44 // |
|
45 // Create new request entry |
|
46 // |
|
47 { |
|
48 return new(ELeave) CAcquireEntry(aTsyReqHandle); |
|
49 } |
|
50 |
|
51 CAcquireEntry::CAcquireEntry(const TTsyReqHandle aTsyReqHandle) |
|
52 // |
|
53 // Constructor |
|
54 // |
|
55 { |
|
56 iTsyReqHandle=aTsyReqHandle; |
|
57 } |
|
58 |
|
59 CAcquireEntry::~CAcquireEntry() |
|
60 // |
|
61 // Destructor |
|
62 // |
|
63 {} |
|
64 |
|
65 void CAcquireEntry::Deque() |
|
66 // |
|
67 // Deque List |
|
68 // |
|
69 { |
|
70 iLink.Deque(); |
|
71 iLink.iPrev=iLink.iNext=NULL; |
|
72 } |
|
73 |
|
74 CAcquireOwnerList::CAcquireOwnerList() |
|
75 {} |
|
76 |
|
77 CAcquireOwnerList::~CAcquireOwnerList() |
|
78 {} |
|
79 |
|
80 CAcquireOwnerList* CAcquireOwnerList::NewL() |
|
81 // |
|
82 // Static function to create new acquire owner list |
|
83 // |
|
84 { |
|
85 CAcquireOwnerList* self=new(ELeave) CAcquireOwnerList(); |
|
86 CleanupStack::PushL(self); |
|
87 self->ConstructL(); |
|
88 CleanupStack::Pop(self); |
|
89 return self; |
|
90 } |
|
91 |
|
92 void CAcquireOwnerList::ConstructL() |
|
93 { |
|
94 iAcquireList.SetOffset(_FOFF(CAcquireEntry,iLink)); |
|
95 } |
|
96 |
|
97 CAcquireEntry* CAcquireOwnerList::FindByTsyReqHandle(const TTsyReqHandle aTsyReqHandle) |
|
98 // |
|
99 // Searches for client interested in taking ownership of call, by its TsyReqHandle |
|
100 // |
|
101 { |
|
102 CAcquireEntry* entry; |
|
103 TDblQueIter<CAcquireEntry> iter(iAcquireList); |
|
104 while(entry = iter++, entry!=NULL) |
|
105 { |
|
106 if(entry->iTsyReqHandle==aTsyReqHandle) |
|
107 return entry; |
|
108 } |
|
109 return NULL; |
|
110 } |
|
111 |
|
112 void CAcquireOwnerList::Remove(CAcquireEntry* aEntry) |
|
113 { |
|
114 aEntry->Deque(); |
|
115 delete aEntry; |
|
116 } |
|
117 |
|
118 // |
|
119 // CHeartbeatRunner - periodic class to count seconds from beginning of call |
|
120 // |
|
121 CHeartbeatRunner* CHeartbeatRunner::NewL(CCallHayes* aCallHayes,CNotifications* aNotificationStore) |
|
122 { |
|
123 CHeartbeatRunner* self=new (ELeave) CHeartbeatRunner(aCallHayes,aNotificationStore); |
|
124 CleanupStack::PushL(self); |
|
125 self->ConstructL(); |
|
126 CleanupStack::Pop(); |
|
127 return self; |
|
128 } |
|
129 |
|
130 CHeartbeatRunner::CHeartbeatRunner(CCallHayes* aCallHayes,CNotifications* aNotificationStore) |
|
131 :iCallHayes(aCallHayes), iNotificationStore(aNotificationStore) |
|
132 {} |
|
133 |
|
134 void CHeartbeatRunner::ConstructL() |
|
135 { |
|
136 iHeartbeat=CHeartbeat::NewL(0); // neutral priority |
|
137 } |
|
138 |
|
139 CHeartbeatRunner::~CHeartbeatRunner() |
|
140 { |
|
141 if (iHeartbeat != NULL) |
|
142 iHeartbeat->Cancel(); |
|
143 delete iHeartbeat; |
|
144 } |
|
145 |
|
146 void CHeartbeatRunner::Start() |
|
147 { |
|
148 iStartTime.UniversalTime(); |
|
149 iHeartbeat->Start(ETwelveOClock,this); |
|
150 } |
|
151 |
|
152 void CHeartbeatRunner::Stop() |
|
153 { |
|
154 iHeartbeat->Cancel(); |
|
155 iTicks=0; |
|
156 } |
|
157 |
|
158 TTimeIntervalSeconds CHeartbeatRunner::CallDuration() const |
|
159 { |
|
160 TTimeIntervalSeconds duration(iTicks); |
|
161 return duration; |
|
162 } |
|
163 |
|
164 // private functions |
|
165 |
|
166 void CHeartbeatRunner::Beat() |
|
167 { |
|
168 iTicks++; |
|
169 iNotificationStore->CheckNotification(iCallHayes,ETimePeriodElapsed); |
|
170 } |
|
171 |
|
172 void CHeartbeatRunner::Synchronize() |
|
173 { |
|
174 TInt ticksMissed = 0; |
|
175 TTime desiredTime = iStartTime + TTimeIntervalMicroSeconds(iTicks * KCallTimerInterval); |
|
176 TTime currentTime; // set current time to now |
|
177 currentTime.UniversalTime(); |
|
178 TTimeIntervalMicroSeconds missedTime = currentTime.MicroSecondsFrom(desiredTime); |
|
179 // Calculate the ticks missed (quickly!) |
|
180 TInt64 missedTimeInt = missedTime.Int64(); // convert the missed time interval to an Int64 |
|
181 ticksMissed = I64INT(missedTimeInt / KCallTimerInterval); |
|
182 // The following loop increments the ticks missed by the same amount, but takes much longer |
|
183 // while (desiredTime < currentTime) |
|
184 // { |
|
185 // desiredTime = desiredTime - TTimeIntervalMicroSeconds(iTickInterval); |
|
186 // ticksMissed++; |
|
187 // } |
|
188 iTicks = iTicks + ticksMissed; |
|
189 LOGTEXT3(_L8("Heartbeat function synchronising - from %d to %d"),iTicks-ticksMissed,iTicks); |
|
190 if (ticksMissed!=0) |
|
191 iNotificationStore->CheckNotification(iCallHayes,ETimePeriodElapsed); |
|
192 } |
|
193 |
|
194 // |
|
195 // CCallHayes - General Call Functionality |
|
196 // |
|
197 void CCallHayes::CloseCall(TAny* aObj) |
|
198 // |
|
199 // Utility func for cleanup stack |
|
200 // |
|
201 { |
|
202 ((CObject*)aObj)->Close(); |
|
203 } |
|
204 |
|
205 CCallHayes::CCallHayes(CATIO* aIo,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
206 : iPhoneGlobals(aPhoneGlobals),iIo(aIo),iInit(aInit) |
|
207 {} |
|
208 |
|
209 void CCallHayes::ConstructL(const TName& aName) |
|
210 // |
|
211 // Initialise Call Information |
|
212 // |
|
213 { |
|
214 LOGTEXT(_L8("Entered CCallHayes::ConstructL()")); |
|
215 iCallInfo.iCallName = aName; |
|
216 iCallInfo.iBearerService.iBearerCaps = RCall::KBearerCapsCompressionUnknown | RCall::KBearerCapsProtocolUnknown; |
|
217 iCallInfo.iBearerService.iBearerSpeed = RCall::EBearerDataUnknown; |
|
218 iCallInfo.iHookStatus = RCall::EHookStatusOn; |
|
219 iCallInfo.iClientPanicOccurred = ENoPanicOccurred; |
|
220 // Read default call preferences from database |
|
221 GetDefaultCallParams(); |
|
222 iCallInfo.iLoanedToClient = EFalse; |
|
223 if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusRinging) |
|
224 { |
|
225 iCallInfo.iMobileStatus = RMobileCall::EStatusRinging; |
|
226 } |
|
227 else |
|
228 { |
|
229 iCallInfo.iMobileStatus = RMobileCall::EStatusIdle; |
|
230 } |
|
231 |
|
232 iQuickInit=CATQuickInit::NewL(iIo,this,iPhoneGlobals); |
|
233 iWaitForNoCarrier=CATWaitForNoCarrier::NewL(iIo,this,iPhoneGlobals); |
|
234 iList=CAcquireOwnerList::NewL(); |
|
235 iCallTimer = CHeartbeatRunner::NewL(this,iPhoneGlobals->iNotificationStore); |
|
236 LOGTEXT2(_L8("iCallTimer = %x"),iCallTimer); |
|
237 } |
|
238 |
|
239 CCallHayes::~CCallHayes() |
|
240 { |
|
241 LOGTEXT(_L8("Entered CCallHayes destructor")); |
|
242 if (Owner()) |
|
243 REINTERPRET_CAST(CLineHayes*,Owner())->RemoveCall(this); |
|
244 iPhoneGlobals->iNotificationStore->RemoveClientFromLastEvents(this); |
|
245 delete iWaitForNoCarrier; |
|
246 delete iList; |
|
247 delete iQuickInit; |
|
248 delete iCallTimer; |
|
249 } |
|
250 |
|
251 CTelObject::TReqMode CCallHayes::ReqModeL(const TInt aIpc) |
|
252 { |
|
253 TReqMode reqMode = CCallBase::ReqModeL(aIpc); |
|
254 if ((reqMode & KReqModeFlowControlObeyed || aIpc==EEtelCallAnswer) && iPhoneGlobals->iPhoneStatus.iDataPortLoaned) |
|
255 { |
|
256 LOGTEXT2(_L8("ReqModeL Leaving with KErrInUse as data port is loaned (aIpc=%d)"),aIpc); |
|
257 User::Leave(KErrInUse); |
|
258 } |
|
259 return reqMode; |
|
260 } |
|
261 |
|
262 TInt CCallHayes::RegisterNotification(const TInt /*aIpc*/) |
|
263 { |
|
264 return KErrNone; |
|
265 } |
|
266 TInt CCallHayes::DeregisterNotification(const TInt /*aIpc*/) |
|
267 { |
|
268 return KErrNone; |
|
269 } |
|
270 |
|
271 |
|
272 void CCallHayes::Init() |
|
273 // |
|
274 // Only CPhoneHayes::Init() is implemented as that is called first |
|
275 // |
|
276 {} |
|
277 |
|
278 |
|
279 TInt CCallHayes::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RCall::TCaps* aCaps) |
|
280 { |
|
281 LOGTEXT(_L8("Call:\tCaps Change Notification lodged")); |
|
282 iPhoneGlobals->iNotificationStore->RegisterNotification(ECallCaps,aTsyReqHandle,this,aCaps); |
|
283 return KErrNone; |
|
284 } |
|
285 |
|
286 TInt CCallHayes::NotifyCapsChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
287 { |
|
288 LOGTEXT(_L8("Call:\tCaps Change Notification cancelled")); |
|
289 iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
290 return KErrNone; |
|
291 } |
|
292 |
|
293 TInt CCallHayes::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus) |
|
294 { |
|
295 LOGTEXT(_L8("Call:\tHook Change Notification lodged")); |
|
296 iPhoneGlobals->iNotificationStore->RegisterNotification(ECallHookChange,aTsyReqHandle,this,aHookStatus); |
|
297 return KErrNone; |
|
298 } |
|
299 |
|
300 TInt CCallHayes::NotifyHookChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
301 { |
|
302 LOGTEXT(_L8("Call:\tHook Change Notification cancelled")); |
|
303 iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
304 return KErrNone; |
|
305 } |
|
306 |
|
307 TInt CCallHayes::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aStatus) |
|
308 { |
|
309 LOGTEXT(_L8("Call:\tStatus Change Notification lodged")); |
|
310 iPhoneGlobals->iNotificationStore->RegisterNotification(ECallStatusChange,aTsyReqHandle,this,aStatus); |
|
311 return KErrNone; |
|
312 } |
|
313 |
|
314 TInt CCallHayes::NotifyStatusChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
315 { |
|
316 LOGTEXT(_L8("Call:\tStatus Change Notification cancelled")); |
|
317 iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
318 return KErrNone; |
|
319 } |
|
320 |
|
321 TInt CCallHayes::NotifyDurationChange(const TTsyReqHandle aTsyReqHandle,TTimeIntervalSeconds* aTime) |
|
322 { |
|
323 LOGTEXT(_L8("Call:\tDuration Change Notification lodged")); |
|
324 iPhoneGlobals->iNotificationStore->RegisterNotification(ECallDurationChange,aTsyReqHandle,this,aTime); |
|
325 return KErrNone; |
|
326 } |
|
327 |
|
328 TInt CCallHayes::NotifyDurationChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
329 { |
|
330 LOGTEXT(_L8("Call:\tDuration Change Notification cancelled")); |
|
331 iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
332 return KErrNone; |
|
333 } |
|
334 |
|
335 TInt CCallHayes::GetInfo(const TTsyReqHandle aTsyReqHandle, RCall::TCallInfo* aCallInfo) |
|
336 { |
|
337 aCallInfo->iCallName = iCallInfo.iCallName; |
|
338 aCallInfo->iStatus = GetCoreCallStatus(); |
|
339 aCallInfo->iHookStatus = iCallInfo.iHookStatus; |
|
340 aCallInfo->iLineName = Owner()->Name(); |
|
341 GetCallDuration(aCallInfo->iDuration); |
|
342 ReqCompleted(aTsyReqHandle,KErrNone); |
|
343 return KErrNone; |
|
344 } |
|
345 |
|
346 TInt CCallHayes::GetStatus(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aCallStatus) |
|
347 { |
|
348 LOGTEXT(_L8("Call:\tGetStatus() called")); |
|
349 *aCallStatus = GetCoreCallStatus(); |
|
350 ReqCompleted(aTsyReqHandle,KErrNone); |
|
351 return KErrNone; |
|
352 } |
|
353 |
|
354 TInt CCallHayes::TransferOwnership(const TTsyReqHandle aTsyReqHandle) |
|
355 // |
|
356 // Transfer call ownership |
|
357 // |
|
358 { |
|
359 LOGTEXT(_L8("Call:\tTransferOwnership called")); |
|
360 if (CheckOwnership(aTsyReqHandle)!=CCallBase::EOwnedTrue) |
|
361 { |
|
362 ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner); |
|
363 return KErrNone; |
|
364 } |
|
365 |
|
366 if(iList->iAcquireList.IsEmpty()) // no one interested in this call ! |
|
367 { |
|
368 ReqCompleted(aTsyReqHandle,KErrEtelNoClientInterestedInThisCall); |
|
369 return KErrNone; |
|
370 } |
|
371 |
|
372 CAcquireEntry* entry=iList->iAcquireList.First(); |
|
373 if (entry) // someone interested in this call |
|
374 { |
|
375 LOGTEXT(_L8("Call:\tTransferOwnership successful")); |
|
376 (void)SetOwnership(entry->iTsyReqHandle); |
|
377 ReqCompleted(entry->iTsyReqHandle,KErrNone); |
|
378 iList->Remove(entry); |
|
379 ReqCompleted(aTsyReqHandle,KErrNone); |
|
380 } |
|
381 return KErrNone; |
|
382 } |
|
383 |
|
384 TInt CCallHayes::AcquireOwnership(const TTsyReqHandle aTsyReqHandle) |
|
385 // |
|
386 // Acquire call Ownership (server has already checked client does not own it) |
|
387 // If call is unowned and idle, this request is completed with CallNotActive. |
|
388 // A call must never be owned and idle concurrently. |
|
389 // |
|
390 { |
|
391 LOGTEXT(_L8("Call:\tAcquireOwnership called")); |
|
392 if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedUnowned) |
|
393 { |
|
394 LOGTEXT(_L8("Call:\tAcquireOwnership unsuccessful as call is not owned already")); |
|
395 ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive); |
|
396 } |
|
397 else |
|
398 { |
|
399 if(iList->iAcquireList.IsEmpty()) |
|
400 // List is empty. Client is the first one to request ownership of the call. |
|
401 { |
|
402 CAcquireEntry* entry=NULL; |
|
403 TRAPD(err,entry=CAcquireEntry::NewL(aTsyReqHandle)); |
|
404 if(err==KErrNone) |
|
405 iList->iAcquireList.AddLast(*entry); |
|
406 else |
|
407 return err; |
|
408 } |
|
409 else |
|
410 // List is not empty. Another client has already requested to acquire ownership of the call. |
|
411 // Only one client can be waiting to acquire ownership at any one time. |
|
412 return KErrInUse; |
|
413 } |
|
414 return KErrNone; |
|
415 } |
|
416 |
|
417 TInt CCallHayes::AcquireOwnershipCancel(const TTsyReqHandle aTsyReqHandle) |
|
418 // |
|
419 // Cancel Acquire call Ownership |
|
420 // |
|
421 { |
|
422 CAcquireEntry* entry=iList->FindByTsyReqHandle(aTsyReqHandle); |
|
423 __ASSERT_ALWAYS(entry!=NULL,Panic(EAcquirerNotFound)); |
|
424 if (entry != NULL) |
|
425 { |
|
426 iList->Remove(entry); |
|
427 ReqCompleted(aTsyReqHandle, KErrCancel); |
|
428 } |
|
429 else |
|
430 { |
|
431 ReqCompleted(aTsyReqHandle, KErrNotFound); |
|
432 } |
|
433 return KErrNone; |
|
434 } |
|
435 |
|
436 TInt CCallHayes::GetBearerServiceInfo(const TTsyReqHandle aTsyReqHandle,RCall::TBearerService* aBearerService) |
|
437 { |
|
438 *aBearerService = iCallInfo.iBearerService; |
|
439 ReqCompleted(aTsyReqHandle,KErrNone); |
|
440 return KErrNone; |
|
441 } |
|
442 |
|
443 TInt CCallHayes::GetCallParams(const TTsyReqHandle aTsyReqHandle, TDes8* aParams) |
|
444 // |
|
445 // Call parameters are only set when connecting a call, so there have no meaning when a |
|
446 // call is not in progress. |
|
447 // |
|
448 { |
|
449 if (RMobileCall::EStatusIdle != iCallInfo.iMobileStatus && |
|
450 RMobileCall::EStatusUnknown != iCallInfo.iMobileStatus ) |
|
451 { |
|
452 TPckg<RCall::TCallParams>* paramsPckg = (TPckg<RCall::TCallParams>*)aParams; |
|
453 RCall::TCallParams& callparams = (*paramsPckg)(); |
|
454 |
|
455 // |
|
456 // Configure basic TCallParams parameters |
|
457 callparams.iSpeakerControl = iCallInfo.iSpeakerControl; |
|
458 callparams.iSpeakerVolume = iCallInfo.iSpeakerVolume; |
|
459 callparams.iInterval = iCallInfo.iInterval; |
|
460 callparams.iWaitForDialTone = iCallInfo.iWaitForDialTone; |
|
461 |
|
462 // |
|
463 // Configure additional params as required |
|
464 if(callparams.ExtensionId()==RMobileCall::KETelMobileCallParamsV1) |
|
465 { |
|
466 // |
|
467 // Configure RMobileCall::TMobileCallParamsV1 parameters |
|
468 RMobileCall::TMobileCallParamsV1Pckg* pckg = (RMobileCall::TMobileCallParamsV1Pckg*)aParams; |
|
469 RMobileCall::TMobileCallParamsV1& params = (*pckg)(); |
|
470 params.iIdRestrict=iCallInfo.iCallParams.iIdRestrict; |
|
471 params.iCug=iCallInfo.iCallParams.iCug; |
|
472 params.iAutoRedial=iCallInfo.iCallParams.iAutoRedial; |
|
473 } |
|
474 else if(callparams.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1) |
|
475 { |
|
476 // |
|
477 // Configure RMobileCall::TMobileDataCallParamsV1 parameters |
|
478 RMobileCall::TMobileDataCallParamsV1Pckg* pckg = (RMobileCall::TMobileDataCallParamsV1Pckg*)aParams; |
|
479 RMobileCall::TMobileDataCallParamsV1& params = (*pckg)(); |
|
480 params.iService=iCallInfo.iCallParams.iService; |
|
481 params.iSpeed=iCallInfo.iCallParams.iSpeed; |
|
482 params.iProtocol=iCallInfo.iCallParams.iProtocol; |
|
483 params.iQoS=iCallInfo.iCallParams.iQoS; |
|
484 params.iRLPVersion=iCallInfo.iCallParams.iRLPVersion; |
|
485 params.iModemToMSWindowSize=iCallInfo.iCallParams.iModemToMSWindowSize; |
|
486 params.iMSToModemWindowSize=iCallInfo.iCallParams.iMSToModemWindowSize; |
|
487 params.iAckTimer=iCallInfo.iCallParams.iAckTimer; |
|
488 params.iRetransmissionAttempts=iCallInfo.iCallParams.iRetransmissionAttempts; |
|
489 params.iResequencingPeriod=iCallInfo.iCallParams.iResequencingPeriod; |
|
490 params.iV42bisReq=iCallInfo.iCallParams.iV42bisReq; |
|
491 params.iV42bisCodewordsNum=iCallInfo.iCallParams.iV42bisCodewordsNum; |
|
492 params.iV42bisMaxStringLength=iCallInfo.iCallParams.iV42bisMaxStringLength; |
|
493 } |
|
494 else if(callparams.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1) |
|
495 { |
|
496 // |
|
497 // Configure RMobileCall::TMobileHscsdCallParamsV1 parameters |
|
498 RMobileCall::TMobileHscsdCallParamsV1Pckg* pckg = (RMobileCall::TMobileHscsdCallParamsV1Pckg*)aParams; |
|
499 RMobileCall::TMobileHscsdCallParamsV1& params = (*pckg)(); |
|
500 params.iWantedAiur=iCallInfo.iCallParams.iWantedAiur; |
|
501 params.iWantedRxTimeSlots=iCallInfo.iCallParams.iWantedRxTimeSlots; |
|
502 params.iMaxTimeSlots=iCallInfo.iCallParams.iMaxTimeSlots; |
|
503 params.iCodings=iCallInfo.iCallParams.iCodings; |
|
504 params.iAsymmetry=iCallInfo.iCallParams.iAsymmetry; |
|
505 params.iUserInitUpgrade=iCallInfo.iCallParams.iUserInitUpgrade; |
|
506 } |
|
507 |
|
508 // |
|
509 // Complete the clients request |
|
510 ReqCompleted(aTsyReqHandle,KErrNone); |
|
511 } |
|
512 else |
|
513 { |
|
514 ReqCompleted(aTsyReqHandle,KErrUnknown); |
|
515 } |
|
516 return KErrNone; |
|
517 } |
|
518 |
|
519 TInt CCallHayes::GetCallDuration(const TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime) |
|
520 { |
|
521 if ( RMobileCall::EStatusConnected != iCallInfo.iMobileStatus && |
|
522 RMobileCall::EStatusDisconnecting != iCallInfo.iMobileStatus) |
|
523 { |
|
524 ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive); |
|
525 return KErrNone; |
|
526 } |
|
527 *aTime = iCallTimer->CallDuration(); |
|
528 ReqCompleted(aTsyReqHandle,KErrNone); |
|
529 return KErrNone; |
|
530 } |
|
531 |
|
532 void CCallHayes::GetCallDuration(TTimeIntervalSeconds& aTime) const |
|
533 { |
|
534 aTime = iCallTimer->CallDuration(); |
|
535 } |
|
536 |
|
537 void CCallHayes::GetDefaultCallParams() |
|
538 { |
|
539 iPhoneGlobals->iConfiguration->GetIntervalPref(iCallInfo.iInterval); |
|
540 iPhoneGlobals->iConfiguration->GetSpeakerSettingPref(iCallInfo.iSpeakerControl); |
|
541 iPhoneGlobals->iConfiguration->GetSpeakerVolumePref(iCallInfo.iSpeakerVolume); |
|
542 iPhoneGlobals->iConfiguration->GetWaitForDialTonePref(iCallInfo.iWaitForDialTone); |
|
543 } |
|
544 |
|
545 void CCallHayes::SetCallParams(const TDesC8* aParams) |
|
546 { |
|
547 if ((*aParams).Length()==0) |
|
548 // Always returns KErrNone |
|
549 GetDefaultCallParams(); |
|
550 else |
|
551 { |
|
552 TPckg<RCall::TCallParams>* paramsPckg = (TPckg<RCall::TCallParams>*)aParams; |
|
553 RCall::TCallParams& callparams = (*paramsPckg)(); |
|
554 iCallInfo.iSpeakerControl = callparams.iSpeakerControl; |
|
555 iCallInfo.iSpeakerVolume = callparams.iSpeakerVolume; |
|
556 iCallInfo.iInterval = callparams.iInterval; |
|
557 iCallInfo.iWaitForDialTone = callparams.iWaitForDialTone; |
|
558 } |
|
559 } |
|
560 |
|
561 TInt CCallHayes::ValidateRequest(const TTsyReqHandle aTsyReqHandle, RCall::TStatus aLineStatus) |
|
562 // |
|
563 // Validating a request |
|
564 // |
|
565 { |
|
566 CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle); |
|
567 if (owned==CCallBase::EOwnedFalse) // call owned by another client |
|
568 { |
|
569 return KErrEtelNotCallOwner; |
|
570 } |
|
571 if (iPhoneGlobals->iPhoneStatus.iLineStatus != aLineStatus) |
|
572 { |
|
573 if (aLineStatus==RCall::EStatusIdle) |
|
574 // implies that this call is already active (assuming an owned call is |
|
575 // an active call) or ringing or unknown |
|
576 { |
|
577 return KErrInUse; |
|
578 } |
|
579 else if (aLineStatus==RCall::EStatusRinging) |
|
580 { |
|
581 return KErrNotReady; |
|
582 } |
|
583 } |
|
584 return KErrNone; |
|
585 } |
|
586 |
|
587 |
|
588 RCall::TStatus CCallHayes::GetCoreCallStatus() |
|
589 { |
|
590 RCall::TStatus coreStatus; |
|
591 if (iCallInfo.iMobileStatus <= RMobileCall::EStatusDisconnecting) |
|
592 //coreStatus = static_cast<RCall::TStatus>(iCallInfo.iMobileStatus); |
|
593 coreStatus = (RCall::TStatus)iCallInfo.iMobileStatus; |
|
594 else |
|
595 switch (iCallInfo.iMobileStatus) |
|
596 { |
|
597 case RMobileCall::EStatusReconnectPending: |
|
598 case RMobileCall::EStatusHold: |
|
599 coreStatus = RCall::EStatusConnected; |
|
600 break; |
|
601 case RMobileCall::EStatusWaitingAlternatingCallSwitch: |
|
602 coreStatus = RCall::EStatusIdle; |
|
603 break; |
|
604 default: |
|
605 coreStatus = RCall::EStatusUnknown; |
|
606 break; |
|
607 } |
|
608 return coreStatus; |
|
609 } |
|
610 |
|
611 TInt CCallHayes::ChangeCallStatus(RMobileCall::TMobileCallStatus aCallStatus) |
|
612 { |
|
613 if (iCallInfo.iMobileStatus != aCallStatus) |
|
614 { |
|
615 iCallInfo.iMobileStatus = aCallStatus; |
|
616 |
|
617 if (aCallStatus == RMobileCall::EStatusIdle) |
|
618 { |
|
619 iCallInfo.iHookStatus = RCall::EHookStatusOn; |
|
620 iPhoneGlobals->iNotificationStore->CheckNotification(this,EBecomeIdle); |
|
621 } |
|
622 else if (aCallStatus != RMobileCall::EStatusUnknown && aCallStatus != RMobileCall::EStatusRinging) |
|
623 { |
|
624 iCallInfo.iHookStatus = RCall::EHookStatusOff; |
|
625 } |
|
626 if (aCallStatus == RMobileCall::EStatusConnected) |
|
627 { |
|
628 iPhoneGlobals->iNotificationStore->CheckNotification(this,EConnected); |
|
629 iIo->Cancel(); |
|
630 TCommConfig aConfigPckg; |
|
631 TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeConnect); |
|
632 if (ret==KErrNone) |
|
633 ret = iIo->ConfigurePort(aConfigPckg); |
|
634 // if (!(iIo->ReadPending())) |
|
635 // iIo->Read(); |
|
636 iCallInfo.iTimeCallBegan.UniversalTime(); |
|
637 return ret; |
|
638 } |
|
639 } |
|
640 return KErrNone; |
|
641 } |
|
642 |
|
643 void CCallHayes::ChangeLineStatus(RCall::TStatus aLineStatus) |
|
644 { |
|
645 iPhoneGlobals->iPhoneStatus.iLineStatus = aLineStatus; |
|
646 } |
|
647 |
|
648 void CCallHayes::SetToIdle() |
|
649 { |
|
650 iWaitForNoCarrier->StopWait(); |
|
651 // Always returns KErrNone |
|
652 (void)SetUnowned(); |
|
653 iPhoneGlobals->iPhoneStatus.iMode = RPhone::EModeIdle; |
|
654 ChangeLineStatus(RCall::EStatusIdle); // line status should be changed first because |
|
655 // ChangeCallStatus is the function which sends |
|
656 // the new event to the Notification Handler, |
|
657 // and this will complete both line and call status |
|
658 // notifications, taking the new statuses from the |
|
659 // CLineHayes and CCallHayes objects. |
|
660 // EStatusIdle always results in KErrNone return value |
|
661 (void)ChangeCallStatus(RMobileCall::EStatusIdle); |
|
662 StopCallTicker(); |
|
663 } |
|
664 |
|
665 void CCallHayes::SetToIdleAndCompleteReq(TTsyReqHandle aTsyReqHandle,TInt aStatus) |
|
666 { |
|
667 SetToIdle(); |
|
668 ReqCompleted(aTsyReqHandle, aStatus); |
|
669 } |
|
670 |
|
671 void CCallHayes::GetCallInfo(TCallInfoIndex* aCallInfoIndex) |
|
672 // |
|
673 // Copied field by field since TCallInfoTSY is different to TCallInfoIndex |
|
674 // |
|
675 { |
|
676 aCallInfoIndex->iInfo.iCallName = iCallInfo.iCallName; |
|
677 aCallInfoIndex->iInfo.iStatus = GetCoreCallStatus(); |
|
678 aCallInfoIndex->iInfo.iCallCapsFlags = 0; |
|
679 } |
|
680 |
|
681 TBool CCallHayes::CheckName(const TDesC& aName) const |
|
682 // |
|
683 // Return TRUE if name is the same as the name of this call |
|
684 { |
|
685 if (iCallInfo.iCallName.CompareF(aName)) |
|
686 return EFalse; |
|
687 else |
|
688 return ETrue; |
|
689 } |
|
690 |
|
691 TCallInfoTSY* CCallHayes::CallInfo() |
|
692 { |
|
693 return &iCallInfo; |
|
694 } |
|
695 |
|
696 void CCallHayes::StartCallTicker() const |
|
697 { |
|
698 iCallTimer->Start(); |
|
699 } |
|
700 |
|
701 void CCallHayes::StopCallTicker() const |
|
702 { |
|
703 iCallTimer->Stop(); |
|
704 } |
|
705 |
|
706 void CCallHayes::ResetIsForIncomingCall() |
|
707 { |
|
708 iIsForIncomingCall=EFalse; |
|
709 } |
|
710 |
|
711 TBool CCallHayes::IsForIncomingCall() const |
|
712 { |
|
713 return iIsForIncomingCall; |
|
714 } |
|
715 |
|
716 void CCallHayes::SetOwnedByTSY() |
|
717 { |
|
718 iIsOwnedByTSY=ETrue; |
|
719 } |
|
720 |
|
721 void CCallHayes::SetUnownedByTSY() |
|
722 { |
|
723 iIsOwnedByTSY=EFalse; |
|
724 } |
|
725 |
|
726 TBool CCallHayes::IsOwnedByTSY() const |
|
727 { |
|
728 return iIsOwnedByTSY; |
|
729 } |
|
730 |
|
731 |
|
732 // |
|
733 // Functions which are supported in one line but not the other |
|
734 // |
|
735 TInt CCallHayes::LoanDataPort(const TTsyReqHandle,RCall::TCommPort*) |
|
736 { |
|
737 return KErrNotSupported; |
|
738 } |
|
739 |
|
740 TInt CCallHayes::LoanDataPortCancel(const TTsyReqHandle) |
|
741 { |
|
742 return KErrNotSupported; |
|
743 } |
|
744 |
|
745 TInt CCallHayes::RecoverDataPort(const TTsyReqHandle) |
|
746 { |
|
747 return KErrNotSupported; |
|
748 } |
|
749 |
|
750 TInt CCallHayes::RecoverDataPortAndRelinquishOwnership() |
|
751 { |
|
752 return KErrNotSupported; |
|
753 } |
|
754 |
|
755 TInt CCallHayes::GetFaxSettings(const TTsyReqHandle,RCall::TFaxSessionSettings*) |
|
756 { |
|
757 return KErrNotSupported; |
|
758 } |
|
759 |
|
760 TInt CCallHayes::SetFaxSettings(const TTsyReqHandle,const RCall::TFaxSessionSettings*) |
|
761 { |
|
762 return KErrNotSupported; |
|
763 } |
|
764 |
|
765 CTelObject* CCallHayes::OpenNewObjectByNameL(const TDesC& /*aName*/) |
|
766 { |
|
767 User::Leave(KErrNotSupported); |
|
768 return NULL; |
|
769 } |
|
770 |
|
771 CTelObject* CCallHayes::OpenNewObjectL(TDes& /*aNewName*/) |
|
772 { |
|
773 User::Leave(KErrNotSupported); |
|
774 return NULL; |
|
775 } |
|
776 |
|
777 TInt CCallHayes::CheckAndSetRegistrationParams(const TInt /*aIpc*/,const TDes8* /*aDes1*/,const TDes8* /*aDes2*/) |
|
778 { |
|
779 return KErrNone; |
|
780 } |
|
781 |
|
782 TInt CCallHayes::ExtFunc(const TTsyReqHandle,const TInt, const TDataPackage&) |
|
783 // |
|
784 // Unsupported in this TSY |
|
785 // |
|
786 { |
|
787 return KErrNotSupported; |
|
788 } |
|
789 |
|
790 /* |
|
791 * CCallMobile class that implements Multimode ETel Mobile Call requests |
|
792 */ |
|
793 |
|
794 CCallMobile::CCallMobile(CATIO* aIo,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
795 : CCallHayes(aIo, aInit, aPhoneGlobals) |
|
796 { |
|
797 } |
|
798 |
|
799 CCallMobile::~CCallMobile() |
|
800 { |
|
801 } |
|
802 |
|
803 CTelObject::TReqMode CCallMobile::ReqModeL(const TInt aIpc) |
|
804 { |
|
805 // ReqModeL is called from the server's CTelObject::ReqAnalyserL |
|
806 // in order to check the type of request it has |
|
807 |
|
808 CTelObject::TReqMode ret=0; |
|
809 switch (aIpc) |
|
810 { |
|
811 // |
|
812 // No Flow Control NOR Multiple Completion |
|
813 // |
|
814 case EMobileCallGetMobileCallCaps: |
|
815 case EMobileCallGetMobileCallStatus: |
|
816 break; |
|
817 |
|
818 case EMobileCallGetMobileDataCallCaps: |
|
819 break; |
|
820 // |
|
821 // Multiple Completion Services with Immediate Server Repost |
|
822 // (Usually Notifications) |
|
823 // |
|
824 case EMobileCallNotifyMobileCallStatusChange: |
|
825 case EMobileCallNotifyMobileCallCapsChange: |
|
826 |
|
827 ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately; |
|
828 break; |
|
829 // |
|
830 // |
|
831 // |
|
832 default: |
|
833 ret=CCallHayes::ReqModeL(aIpc); |
|
834 break; |
|
835 } |
|
836 |
|
837 return ret; |
|
838 } |
|
839 |
|
840 |
|
841 TInt CCallMobile::NumberOfSlotsL(const TInt aIpc) |
|
842 { |
|
843 // NumberOfSlotsL is called by the server when it is registering a new notification |
|
844 // It enables the TSY to tell the server how many buffer slots to allocate for |
|
845 // "repost immediately" notifications that may trigger before clients collect them |
|
846 |
|
847 TInt numberOfSlots=1; |
|
848 switch (aIpc) |
|
849 { |
|
850 case EMobileCallNotifyMobileCallStatusChange: |
|
851 case EMobileCallNotifyMobileCallCapsChange: |
|
852 LOGTEXT(_L8("CCallMobile: Registered with 5 slots")); |
|
853 numberOfSlots=5; |
|
854 break; |
|
855 default: |
|
856 numberOfSlots = CCallBase::NumberOfSlotsL(aIpc); |
|
857 break; |
|
858 } |
|
859 return numberOfSlots; |
|
860 } |
|
861 |
|
862 |
|
863 TInt CCallMobile::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc, |
|
864 const TDataPackage& aPackage) |
|
865 { |
|
866 // ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request |
|
867 // for the TSY to process |
|
868 // A request handle, request type and request data are passed to the TSY |
|
869 |
|
870 TAny* dataPtr=aPackage.Ptr1(); |
|
871 |
|
872 // The request data has to extracted from TDataPackage and the TAny* pointers have to |
|
873 // be "cast" to the expected request data type |
|
874 |
|
875 switch (aIpc) |
|
876 { |
|
877 // |
|
878 // No Flow Control NOR Multiple Completion |
|
879 // |
|
880 case EMobileCallGetMobileCallCaps: |
|
881 return GetMobileCallCaps(aTsyReqHandle, aPackage.Des1n()); |
|
882 |
|
883 case EMobileCallGetMobileCallStatus: |
|
884 return GetMobileCallStatus(aTsyReqHandle, |
|
885 REINTERPRET_CAST(RMobileCall::TMobileCallStatus*,dataPtr)); |
|
886 // |
|
887 // Multiple Completion Services with Immediate Server Repost |
|
888 // (Usually Notifications) |
|
889 // |
|
890 case EMobileCallNotifyMobileCallStatusChange: |
|
891 return NotifyMobileCallStatusChange(aTsyReqHandle, |
|
892 REINTERPRET_CAST(RMobileCall::TMobileCallStatus*, dataPtr)); |
|
893 |
|
894 case EMobileCallNotifyMobileCallCapsChange: |
|
895 return NotifyMobileCallCapsChange(aTsyReqHandle, aPackage.Des1n()); |
|
896 |
|
897 // |
|
898 // Cancels |
|
899 // |
|
900 case EMobileCallNotifyMobileCallStatusChangeCancel: |
|
901 return NotifyMobileCallStatusChangeCancel(aTsyReqHandle); |
|
902 |
|
903 case EMobileCallNotifyMobileCallCapsChangeCancel: |
|
904 return NotifyMobileCallCapsChangeCancel(aTsyReqHandle); |
|
905 |
|
906 default: |
|
907 return KErrNotSupported; |
|
908 } |
|
909 } |
|
910 |
|
911 TInt CCallMobile::CancelService(const TInt aIpc, const TTsyReqHandle aTsyReqHandle) |
|
912 { |
|
913 // CancelService is called by the server when it is "cleaning-up" any still outstanding |
|
914 // asynchronous requests before closing a client's sub-session. |
|
915 // This will happen if a client closes its R-class handle without cancelling outstanding |
|
916 // asynchronous requests. |
|
917 |
|
918 switch (aIpc) |
|
919 { |
|
920 case EMobileCallNotifyMobileCallStatusChange: |
|
921 return NotifyMobileCallStatusChangeCancel(aTsyReqHandle); |
|
922 case EMobileCallNotifyMobileCallCapsChange: |
|
923 return NotifyMobileCallCapsChangeCancel(aTsyReqHandle); |
|
924 default: |
|
925 return CCallBase::CancelService(aIpc,aTsyReqHandle); |
|
926 } |
|
927 } |
|
928 |
|
929 TInt CCallMobile::GetMobileCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps) |
|
930 { |
|
931 LOGTEXT(_L8("CCallMobile: :GetMobileCallCaps called")); |
|
932 |
|
933 RMobileCall::TMobileCallCapsV1Pckg *capsPckg = REINTERPRET_CAST(RMobileCall::TMobileCallCapsV1Pckg *,aCaps); |
|
934 RMobileCall::TMobileCallCapsV1& caps = (*capsPckg)(); |
|
935 // Always returns KErrNone |
|
936 (void)CollateCurrentMobileCaps(aTsyReqHandle, &caps.iCallControlCaps); |
|
937 caps.iCallEventCaps=0; // no call events are supported |
|
938 |
|
939 ReqCompleted(aTsyReqHandle,KErrNone); |
|
940 return KErrNone; |
|
941 } |
|
942 |
|
943 TInt CCallMobile::GetCaps(const TTsyReqHandle aTsyReqHandle,RCall::TCaps* aCallCaps) |
|
944 { |
|
945 (void)CollateCurrentCoreCaps(aTsyReqHandle, reinterpret_cast<TUint32*>(&aCallCaps->iFlags)); |
|
946 ReqCompleted(aTsyReqHandle,KErrNone); |
|
947 return KErrNone; |
|
948 } |
|
949 |
|
950 TBool CCallMobile::CollateCurrentMobileCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps) |
|
951 { |
|
952 CollateCoreCaps(aTsyReqHandle, aCallCaps); |
|
953 if (iMobileCaps.iCallControlCaps != *aCallCaps) |
|
954 { |
|
955 iMobileCaps.iCallControlCaps = *aCallCaps; |
|
956 return ETrue; |
|
957 } |
|
958 return EFalse; |
|
959 } |
|
960 |
|
961 TBool CCallMobile::CollateCurrentCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps) |
|
962 { |
|
963 CollateCoreCaps(aTsyReqHandle, aCallCaps); |
|
964 if (iCaps.iFlags != *aCallCaps) |
|
965 { |
|
966 iCaps.iFlags = *aCallCaps; |
|
967 return ETrue; |
|
968 } |
|
969 return EFalse; |
|
970 } |
|
971 |
|
972 TInt CCallMobile::NotifyMobileCallCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps) |
|
973 { |
|
974 LOGTEXT(_L8("CCallMobile::NotifyMobileCallCapsChange lodged")); |
|
975 iPhoneGlobals->iNotificationStore->RegisterNotification(ECallMobileCaps,aTsyReqHandle,this,aCaps); |
|
976 return KErrNone; |
|
977 } |
|
978 |
|
979 TInt CCallMobile::NotifyMobileCallCapsChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
980 { |
|
981 LOGTEXT(_L8("CCallMobile::NotifyMobileCallCapsChangeCancel called")); |
|
982 iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
983 return KErrNone; |
|
984 } |
|
985 |
|
986 TInt CCallMobile::GetMobileCallStatus(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus) |
|
987 { |
|
988 LOGTEXT(_L8("CCallMobile::GetMobileCallStatus called")); |
|
989 *aStatus=iCallInfo.iMobileStatus; |
|
990 ReqCompleted(aTsyReqHandle,KErrNone); |
|
991 return KErrNone; |
|
992 } |
|
993 |
|
994 TInt CCallMobile::NotifyMobileCallStatusChange(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus) |
|
995 { |
|
996 LOGTEXT(_L8("CCallMobile::NotifyMobileCallStatusChange lodged")); |
|
997 iPhoneGlobals->iNotificationStore->RegisterNotification(EMobileCallStatusChange,aTsyReqHandle,this,aStatus); |
|
998 return KErrNone; |
|
999 } |
|
1000 |
|
1001 TInt CCallMobile::NotifyMobileCallStatusChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
1002 { |
|
1003 LOGTEXT(_L8("CCallMobile::NotifyMobileCallStatusChangeCancel called")); |
|
1004 iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
1005 return KErrNone; |
|
1006 } |
|
1007 |
|
1008 // |
|
1009 // CCallMobileVoice - Voice Specific Call Functionality |
|
1010 // |
|
1011 |
|
1012 CCallMobileVoice* CCallMobileVoice::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName) |
|
1013 { |
|
1014 CCallMobileVoice* voiceCall=new(ELeave) CCallMobileVoice(aATIO,aInit,aPhoneGlobals); |
|
1015 TCleanupItem newCallVoiceHayesClose(CloseCall,voiceCall); |
|
1016 CleanupStack::PushL(newCallVoiceHayesClose); |
|
1017 voiceCall->ConstructL(aName); |
|
1018 CleanupStack::Pop(); |
|
1019 return voiceCall; |
|
1020 } |
|
1021 |
|
1022 CCallMobileVoice::CCallMobileVoice(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
1023 : CCallMobile(aATIO,aInit,aPhoneGlobals) |
|
1024 {} |
|
1025 |
|
1026 void CCallMobileVoice::ConstructL(const TName& aName) |
|
1027 { |
|
1028 CCallHayes::ConstructL(aName); |
|
1029 iCallInfo.iLineOwnerName = KVoiceLineName; |
|
1030 iDialVoice=CATDialVoice::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1031 iAnswerVoice=CATAnswerVoice::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1032 iHangUpVoice=CATHangUpVoice::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1033 } |
|
1034 |
|
1035 CCallMobileVoice::~CCallMobileVoice() |
|
1036 // |
|
1037 // Removes itself from array of calls in CLineMobileVoice |
|
1038 // |
|
1039 { |
|
1040 delete iDialVoice; |
|
1041 delete iAnswerVoice; |
|
1042 delete iHangUpVoice; |
|
1043 } |
|
1044 |
|
1045 void CCallMobileVoice::CollateCoreCaps(const TTsyReqHandle /*aTsyReqHandle*/, TUint32* aCallCaps) |
|
1046 { |
|
1047 *aCallCaps = RCall::KCapsVoice; |
|
1048 |
|
1049 // Voice calls can be manipulated by any client, not just owner so set as many caps as possible |
|
1050 if (iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent) |
|
1051 { |
|
1052 *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect); |
|
1053 |
|
1054 TInt ret=KErrNone; |
|
1055 if (!iIsForIncomingCall) |
|
1056 { |
|
1057 if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) |
|
1058 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1059 } |
|
1060 else |
|
1061 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1062 |
|
1063 if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)) |
|
1064 *aCallCaps |= RCall::KCapsAnswer; |
|
1065 |
|
1066 if (iCallInfo.iMobileStatus==RMobileCall::EStatusConnected) |
|
1067 *aCallCaps |= RCall::KCapsHangUp; |
|
1068 } |
|
1069 } |
|
1070 |
|
1071 TInt CCallMobileVoice::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber) |
|
1072 // |
|
1073 // Dial a voice call |
|
1074 // |
|
1075 { |
|
1076 SetCallParams(aCallParams); |
|
1077 LOGTEXT(_L8("VoiceCall:\tSubmitting Dial command for Voice call")); |
|
1078 if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusIdle) |
|
1079 { |
|
1080 (void)SetOwnership(aTsyReqHandle); |
|
1081 iDialVoice->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo); |
|
1082 return KErrNone; |
|
1083 } |
|
1084 else |
|
1085 { |
|
1086 return KErrInUse; |
|
1087 } |
|
1088 } |
|
1089 |
|
1090 TInt CCallMobileVoice::DialCancel(const TTsyReqHandle aTsyReqHandle) |
|
1091 /** |
|
1092 * Cancel the dial request if possible |
|
1093 */ |
|
1094 { |
|
1095 LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Dial command for Voice call")); |
|
1096 iDialVoice->CancelCommand(aTsyReqHandle); |
|
1097 return KErrNone; |
|
1098 } |
|
1099 |
|
1100 TInt CCallMobileVoice::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams) |
|
1101 /** |
|
1102 * If there is no waiting call, will wait for one and then answer it. If there is, it will |
|
1103 * answer immediately. |
|
1104 */ |
|
1105 { |
|
1106 CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle); |
|
1107 TInt ret=KErrNone; |
|
1108 if (owned==CCallBase::EOwnedFalse) // call owned by another client |
|
1109 { |
|
1110 ret=KErrEtelNotCallOwner; |
|
1111 } |
|
1112 else |
|
1113 { |
|
1114 if (!iIsForIncomingCall) |
|
1115 { |
|
1116 if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) |
|
1117 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1118 } |
|
1119 else |
|
1120 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1121 } |
|
1122 if (ret==KErrNone) |
|
1123 { |
|
1124 CLineHayes* line = STATIC_CAST(CLineHayes*,Owner()); |
|
1125 STATIC_CAST(CPhoneHayes*,line->Owner())->CancelOtherRingingCall(line); |
|
1126 line->FreePreAllocCallIfNecessary(); |
|
1127 SetCallParams(aCallParams); |
|
1128 if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging) |
|
1129 { |
|
1130 (void)SetOwnership(aTsyReqHandle); |
|
1131 LOGTEXT(_L8("VoiceCall:\tSubmitting Answer command")); |
|
1132 iAnswerVoice->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
1133 } |
|
1134 else // This call is now a client-designated Incoming Call object. |
|
1135 { |
|
1136 iIsForIncomingCall=ETrue; |
|
1137 iAnswerTsyReqHandle = aTsyReqHandle; |
|
1138 } |
|
1139 return KErrNone; |
|
1140 } |
|
1141 ReqCompleted(aTsyReqHandle,ret); |
|
1142 return KErrNone; |
|
1143 } |
|
1144 |
|
1145 |
|
1146 TInt CCallMobileVoice::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle) |
|
1147 { |
|
1148 LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Answer command")); |
|
1149 if (iIsForIncomingCall) |
|
1150 { |
|
1151 iIsForIncomingCall=EFalse; |
|
1152 ReqCompleted(aTsyReqHandle,KErrCancel); |
|
1153 } |
|
1154 else |
|
1155 iAnswerVoice->CancelCommand(aTsyReqHandle); |
|
1156 return KErrNone; |
|
1157 } |
|
1158 |
|
1159 void CCallMobileVoice::AnswerImmediately() |
|
1160 { |
|
1161 (void)SetOwnership(iAnswerTsyReqHandle); |
|
1162 // EStatusRinging always results in KErrNone return value |
|
1163 (void) ChangeCallStatus(RMobileCall::EStatusRinging); |
|
1164 iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred); |
|
1165 iIsForIncomingCall=EFalse; |
|
1166 // this must be after the check notification as CNotifications |
|
1167 // asks line for info about the call which Is For Incoming Call |
|
1168 LOGTEXT(_L8("VoiceCall:\tSubmitting Answer command")); |
|
1169 iAnswerVoice->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo); |
|
1170 } |
|
1171 |
|
1172 TInt CCallMobileVoice::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* /*aCallParams*/) |
|
1173 { |
|
1174 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
1175 return KErrNone; |
|
1176 } |
|
1177 |
|
1178 TInt CCallMobileVoice::ConnectCancel(const TTsyReqHandle aTsyReqHandle) |
|
1179 { |
|
1180 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
1181 return KErrNone; |
|
1182 } |
|
1183 |
|
1184 TInt CCallMobileVoice::HangUp(const TTsyReqHandle aTsyReqHandle) |
|
1185 { |
|
1186 if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse) |
|
1187 { |
|
1188 ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner); |
|
1189 return KErrNone; |
|
1190 } |
|
1191 if ((iCallInfo.iMobileStatus!=RMobileCall::EStatusIdle) && |
|
1192 (iCallInfo.iMobileStatus!=RMobileCall::EStatusDisconnecting)) |
|
1193 { |
|
1194 LOGTEXT(_L8("VoiceCall:\tSubmitting Hang Up command")); |
|
1195 iHangUpVoice->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
1196 return KErrNone; |
|
1197 } |
|
1198 else |
|
1199 { |
|
1200 // Call not in a state to be terminated - but return KErrNone |
|
1201 ReqCompleted(aTsyReqHandle,KErrNone); |
|
1202 return KErrNone; |
|
1203 } |
|
1204 } |
|
1205 |
|
1206 TInt CCallMobileVoice::HangUpCancel(const TTsyReqHandle aTsyReqHandle) |
|
1207 // |
|
1208 // Cancel the hang up command. |
|
1209 // |
|
1210 { |
|
1211 LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Hang Up command")); |
|
1212 iHangUpVoice->Stop(aTsyReqHandle); |
|
1213 return KErrNone; |
|
1214 } |
|
1215 |
|
1216 TInt CCallMobileVoice::RelinquishOwnership() |
|
1217 { |
|
1218 // |
|
1219 // Called by server to tell TSY to either pass ownership on to another interested client |
|
1220 // or hang up immediately. If call is currently connecting, RelinquishOwnershipComplete |
|
1221 // will be called once cancelling has finished. |
|
1222 // |
|
1223 LOGTEXT(_L8("VoiceCall:\tRelinquish Ownership")); |
|
1224 if(iList->iAcquireList.IsEmpty()) |
|
1225 { |
|
1226 if (iDialVoice->IsPreConnectInProgress()) |
|
1227 { |
|
1228 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1229 return KErrNone; |
|
1230 } |
|
1231 switch(iCallInfo.iMobileStatus) |
|
1232 { |
|
1233 case RMobileCall::EStatusConnected: |
|
1234 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1235 iHangUpVoice->ExecuteCommand(0, NULL, &iCallInfo); |
|
1236 break; |
|
1237 case RMobileCall::EStatusDialling: |
|
1238 case RMobileCall::EStatusConnecting: |
|
1239 case RMobileCall::EStatusAnswering: |
|
1240 case RMobileCall::EStatusDisconnecting: |
|
1241 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1242 break; |
|
1243 default: |
|
1244 if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneInitialising) |
|
1245 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1246 else |
|
1247 RelinquishOwnershipCompleted(KErrNone); |
|
1248 break; |
|
1249 } |
|
1250 return KErrNone; |
|
1251 } |
|
1252 CAcquireEntry* entry=iList->iAcquireList.First(); |
|
1253 if (entry) |
|
1254 { |
|
1255 (void)SetOwnership(entry->iTsyReqHandle); |
|
1256 ReqCompleted(entry->iTsyReqHandle,KErrNone); |
|
1257 iList->Remove(entry); |
|
1258 } |
|
1259 RelinquishOwnershipCompleted(KErrNone); |
|
1260 return KErrNone; |
|
1261 } |
|
1262 |
|
1263 TInt CCallMobileVoice::RecoverDataPortAndRelinquishOwnership() |
|
1264 { |
|
1265 RecoverDataPortAndRelinquishOwnershipCompleted(KErrNotSupported); |
|
1266 return KErrNone; |
|
1267 } |
|
1268 |
|
1269 TInt CCallMobileVoice::LoanDataPort(const TTsyReqHandle aTsyReqHandle, RCall::TCommPort* /* aCommPort*/) |
|
1270 { |
|
1271 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
1272 return KErrNone; |
|
1273 } |
|
1274 |
|
1275 TInt CCallMobileVoice::LoanDataPortCancel(const TTsyReqHandle aTsyReqHandle) |
|
1276 { |
|
1277 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
1278 return KErrNone; |
|
1279 } |
|
1280 |
|
1281 TInt CCallMobileVoice::RecoverDataPort(const TTsyReqHandle aTsyReqHandle) |
|
1282 { |
|
1283 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
1284 return KErrNone; |
|
1285 } |
|
1286 |
|
1287 |
|
1288 // |
|
1289 // |
|
1290 // CCallMobileData - Data Specific Call Functionality |
|
1291 // |
|
1292 // |
|
1293 |
|
1294 CCallMobileData* CCallMobileData::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName) |
|
1295 { |
|
1296 CCallMobileData* dataCall=new(ELeave) CCallMobileData(aATIO,aInit,aPhoneGlobals); |
|
1297 TCleanupItem newCallDataHayesClose(CloseCall,dataCall); |
|
1298 CleanupStack::PushL(newCallDataHayesClose); |
|
1299 dataCall->ConstructL(aName); |
|
1300 CleanupStack::Pop(); |
|
1301 return dataCall; |
|
1302 } |
|
1303 |
|
1304 CCallMobileData::CCallMobileData(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
1305 : CCallMobile(aATIO,aInit,aPhoneGlobals) |
|
1306 {} |
|
1307 |
|
1308 void CCallMobileData::ConstructL(const TName& aName) |
|
1309 { |
|
1310 CCallHayes::ConstructL(aName); |
|
1311 iCallInfo.iLineOwnerName = KDataLineName; |
|
1312 iDialData=CATDialData::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1313 iAnswerData=CATAnswerData::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1314 iSetCBST=CATSetCBST::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1315 iConnectData=CATConnectData::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1316 iHangUpData=CATHangUpData::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1317 iATSetToOnlineDataMode=CATSetToOnlineDataMode::NewL(iIo,this,iInit,iPhoneGlobals); |
|
1318 } |
|
1319 |
|
1320 CCallMobileData::~CCallMobileData() |
|
1321 // |
|
1322 // Removes itself from array of calls in CLineMobileData |
|
1323 // |
|
1324 { |
|
1325 delete iDialData; |
|
1326 delete iSetCBST; |
|
1327 delete iAnswerData; |
|
1328 delete iConnectData; |
|
1329 delete iHangUpData; |
|
1330 delete iATSetToOnlineDataMode; |
|
1331 } |
|
1332 |
|
1333 TInt CCallMobileData::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc, |
|
1334 const TDataPackage& aPackage) |
|
1335 /** |
|
1336 * Process the IPC locally, otherwise delegate to our base class. |
|
1337 */ |
|
1338 { |
|
1339 switch (aIpc) |
|
1340 { |
|
1341 case EMobileCallGetMobileDataCallCaps: |
|
1342 return GetMobileDataCallCaps(aTsyReqHandle, aPackage.Des1n()); |
|
1343 default: |
|
1344 // Delegate the processing of the IPC to our base class |
|
1345 return CCallMobile::ExtFunc(aTsyReqHandle,aIpc,aPackage); |
|
1346 } |
|
1347 } |
|
1348 |
|
1349 |
|
1350 TInt CCallMobileData::GetMobileDataCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps) |
|
1351 { |
|
1352 LOGTEXT(_L8("CCallMobileData::GetMobileDataCallCaps called")); |
|
1353 |
|
1354 // |
|
1355 // This is a synchronous client request so this method must complete quickly. |
|
1356 // The call caps returned are those which were discovered during the |
|
1357 // intialisation of the TSY (see ATINIT.CPP). |
|
1358 TPckg<RMobileCall::TMobileCallDataCapsV1>* pckg = (TPckg<RMobileCall::TMobileCallDataCapsV1>*)aCaps; |
|
1359 RMobileCall::TMobileCallDataCapsV1& caps = (*pckg)(); |
|
1360 caps=iPhoneGlobals->iCallDataCaps; |
|
1361 ReqCompleted(aTsyReqHandle,KErrNone); |
|
1362 return KErrNone; |
|
1363 } |
|
1364 |
|
1365 void CCallMobileData::CollateCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps) |
|
1366 { |
|
1367 *aCallCaps = RCall::KCapsData; |
|
1368 if (iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent) |
|
1369 { |
|
1370 CCallBase::TCallOwnership owner = CheckOwnership(aTsyReqHandle); |
|
1371 if (ValidateRequest(aTsyReqHandle,RCall::EStatusIdle)==KErrNone) |
|
1372 *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect); |
|
1373 TInt ret=KErrNone; |
|
1374 if (owner==CCallBase::EOwnedFalse) // call owned by another client |
|
1375 ret=KErrEtelNotCallOwner; |
|
1376 else |
|
1377 { |
|
1378 if (!iIsForIncomingCall) |
|
1379 { |
|
1380 if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) |
|
1381 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1382 } |
|
1383 else |
|
1384 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1385 } |
|
1386 if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)) |
|
1387 *aCallCaps |= RCall::KCapsAnswer; |
|
1388 if ((owner==CCallBase::EOwnedTrue || owner==CCallBase::EOwnedPriorityClient) |
|
1389 && iCallInfo.iMobileStatus==RMobileCall::EStatusConnected) |
|
1390 { |
|
1391 *aCallCaps |= RCall::KCapsHangUp; |
|
1392 if (iCallInfo.iLoanedToClient==EFalse) |
|
1393 *aCallCaps |= RCall::KCapsLoanDataPort; |
|
1394 else |
|
1395 *aCallCaps |= RCall::KCapsRecoverDataPort; |
|
1396 } |
|
1397 } |
|
1398 } |
|
1399 |
|
1400 TInt CCallMobileData::AssembleCBSTSetString(TBuf8<KGenericBufferSize>& aTxBuffer) |
|
1401 /** |
|
1402 * This funciton assembles a +CBST= string ready to be sent to the modem using |
|
1403 * the values from CCallHayes::iCallInfo. |
|
1404 * This utility funciton is used by objects created and owned by this class. |
|
1405 * This has been done to reduce code size. |
|
1406 * @return KErrNone if and only if CBST string assembled |
|
1407 */ |
|
1408 { |
|
1409 TInt ret(KErrNone); // Return value of this function |
|
1410 |
|
1411 TInt speed(0); // these are the names that etsi use |
|
1412 TInt name(0); // these are the names that etsi use |
|
1413 TInt ce(0); // these are the names that etsi use |
|
1414 TBool speedSet(ETrue); |
|
1415 TBool nameSet(ETrue); |
|
1416 TBool ceSet(ETrue); |
|
1417 |
|
1418 switch (iCallInfo.iCallParams.iService) |
|
1419 { |
|
1420 case RMobileCall::EServiceDataCircuitAsync: |
|
1421 name = 0; |
|
1422 break; |
|
1423 case RMobileCall::EServiceDataCircuitAsyncRdi: |
|
1424 name = 4; |
|
1425 break; |
|
1426 case RMobileCall::EServiceDataCircuitSync: |
|
1427 name = 1; |
|
1428 break; |
|
1429 case RMobileCall::EServiceDataCircuitSyncRdi: |
|
1430 name = 5; |
|
1431 break; |
|
1432 case RMobileCall::EServicePADAsyncUDI: |
|
1433 name = 2; |
|
1434 break; |
|
1435 case RMobileCall::EServicePADAsyncRDI: |
|
1436 name = 6; |
|
1437 break; |
|
1438 case RMobileCall::EServicePacketAccessSyncUDI: |
|
1439 name = 3; |
|
1440 break; |
|
1441 case RMobileCall::EServicePacketAccessSyncRDI: |
|
1442 name = 7; |
|
1443 break; |
|
1444 case RMobileCall::EServiceUnspecified: // taking the default value of 0 |
|
1445 default: |
|
1446 nameSet=EFalse; |
|
1447 break; |
|
1448 } |
|
1449 |
|
1450 switch(iCallInfo.iCallParams.iQoS) |
|
1451 { |
|
1452 case RMobileCall::EQoSTransparent: |
|
1453 ce = 0; |
|
1454 break; |
|
1455 case RMobileCall::EQosTransparentPreferred: |
|
1456 ce = 2; |
|
1457 break; |
|
1458 case RMobileCall::EQoSNonTransparent: |
|
1459 ce = 1; |
|
1460 break; |
|
1461 case RMobileCall::EQosNonTransparentPreferred: |
|
1462 ce = 3; |
|
1463 break; |
|
1464 case RMobileCall::EQoSUnspecified: |
|
1465 default: |
|
1466 ceSet=EFalse; |
|
1467 break; |
|
1468 } |
|
1469 |
|
1470 switch(iCallInfo.iCallParams.iSpeed) |
|
1471 { |
|
1472 case RMobileCall::ESpeedAutobauding: |
|
1473 speed = 0; |
|
1474 break; |
|
1475 |
|
1476 case RMobileCall::ESpeed2400: |
|
1477 { |
|
1478 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV22bis) |
|
1479 speed = 4; |
|
1480 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1481 speed = 36; |
|
1482 else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1483 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1484 speed = 68; |
|
1485 else |
|
1486 speedSet=EFalse; |
|
1487 break; |
|
1488 } |
|
1489 case RMobileCall::ESpeed4800: |
|
1490 { |
|
1491 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV32) |
|
1492 speed = 6; |
|
1493 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1494 speed = 38; |
|
1495 else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1496 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1497 speed = 70; |
|
1498 else |
|
1499 speedSet=EFalse; |
|
1500 break; |
|
1501 } |
|
1502 case RMobileCall::ESpeed9600: |
|
1503 { |
|
1504 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV32) |
|
1505 speed = 7; |
|
1506 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34) |
|
1507 speed = 12; |
|
1508 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1509 speed = 39; |
|
1510 else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1511 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1512 speed = 71; |
|
1513 else |
|
1514 speedSet=EFalse; |
|
1515 break; |
|
1516 } |
|
1517 case RMobileCall::ESpeed14400: |
|
1518 { |
|
1519 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34) |
|
1520 speed = 14; |
|
1521 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1522 speed = 43; |
|
1523 else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1524 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1525 speed = 75; |
|
1526 else |
|
1527 speedSet=EFalse; |
|
1528 break; |
|
1529 } |
|
1530 case RMobileCall::ESpeed19200: |
|
1531 { |
|
1532 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34) |
|
1533 speed = 15; |
|
1534 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1535 speed = 47; |
|
1536 else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1537 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1538 speed = 79; |
|
1539 else |
|
1540 speedSet=EFalse; |
|
1541 break; |
|
1542 } |
|
1543 case RMobileCall::ESpeed28800: |
|
1544 { |
|
1545 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34) |
|
1546 speed = 16; |
|
1547 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1548 speed = 48; |
|
1549 else if ((iCallInfo.iCallParams.iProtocol ==RMobileCall:: EProtocolV110) || |
|
1550 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1551 speed = 80; |
|
1552 else |
|
1553 speedSet=EFalse; |
|
1554 break; |
|
1555 } |
|
1556 case RMobileCall::ESpeed38400: |
|
1557 { |
|
1558 if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1559 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1560 speed = 81; |
|
1561 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1562 speed = 49; |
|
1563 else |
|
1564 speedSet=EFalse; |
|
1565 break; |
|
1566 } |
|
1567 case RMobileCall::ESpeed48000: |
|
1568 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1569 speed = 50; |
|
1570 else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1571 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1572 speed = 82; |
|
1573 else |
|
1574 speedSet=EFalse; |
|
1575 break; |
|
1576 case RMobileCall::ESpeed56000: |
|
1577 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120) |
|
1578 speed = 51; |
|
1579 else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) || |
|
1580 (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing)) |
|
1581 speed = 83; |
|
1582 else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolBitTransparent) |
|
1583 speed = 115; |
|
1584 else |
|
1585 speedSet=EFalse; |
|
1586 break; |
|
1587 case RMobileCall::ESpeed64000: |
|
1588 if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolBitTransparent) |
|
1589 speed = 116; |
|
1590 else |
|
1591 speedSet=EFalse; |
|
1592 break; |
|
1593 |
|
1594 case RMobileCall::ESpeed33600: // this baud rate is not currently used in the etsi table |
|
1595 case RMobileCall::ESpeedUnspecified: |
|
1596 default: |
|
1597 speedSet=EFalse; |
|
1598 break; |
|
1599 } |
|
1600 |
|
1601 // |
|
1602 // Try to assemble as much of the +CBST= command as we can. |
|
1603 // If we do not have a <speed> value we can not send the command. |
|
1604 // If we do not have a <ce> value then we can send a command giving only <speed> and <name>. |
|
1605 // etc... |
|
1606 if(speedSet) |
|
1607 { |
|
1608 aTxBuffer.Zero(); // Clear tx buffer |
|
1609 |
|
1610 // Append +CBST= and the <speed> parameter |
|
1611 aTxBuffer.Append(KDataCallBearerServiceType); |
|
1612 aTxBuffer.AppendNum(speed); |
|
1613 |
|
1614 if(nameSet) |
|
1615 { |
|
1616 // Append the <name> parameter |
|
1617 aTxBuffer.Append(TChar(',')); |
|
1618 aTxBuffer.AppendNum(name); |
|
1619 |
|
1620 if(ceSet) |
|
1621 { |
|
1622 // Append the <ce> parameter |
|
1623 aTxBuffer.Append(TChar(',')); |
|
1624 aTxBuffer.AppendNum(ce); |
|
1625 } |
|
1626 } |
|
1627 |
|
1628 // Append final \r char to AT command |
|
1629 aTxBuffer.Append(TChar('\r')); |
|
1630 } |
|
1631 else |
|
1632 { |
|
1633 // We have not have enough info to create a +CBST= string |
|
1634 ret=KErrArgument; |
|
1635 } |
|
1636 |
|
1637 return ret; |
|
1638 } |
|
1639 |
|
1640 |
|
1641 |
|
1642 TInt CCallMobileData::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber) |
|
1643 // |
|
1644 // Dial a data call |
|
1645 // |
|
1646 { |
|
1647 TInt ret(KErrNone); |
|
1648 |
|
1649 SetDataCallParams(aCallParams); |
|
1650 |
|
1651 ret=ValidateRequest(aTsyReqHandle,RCall::EStatusIdle); |
|
1652 if (ret==KErrNone) |
|
1653 { |
|
1654 (void)SetOwnership(aTsyReqHandle); |
|
1655 LOGTEXT(_L8("DataCall:\tSubmitting Dial command for Data call")); |
|
1656 iDialData->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo); |
|
1657 } |
|
1658 else |
|
1659 ReqCompleted(aTsyReqHandle,ret); // An error occurred |
|
1660 |
|
1661 return KErrNone; // Real return code is returned to client thru request completion |
|
1662 } |
|
1663 |
|
1664 |
|
1665 TInt CCallMobileData::DialCancel(const TTsyReqHandle aTsyReqHandle) |
|
1666 // |
|
1667 // Cancel the dial request if possible |
|
1668 // |
|
1669 { |
|
1670 LOGTEXT(_L8("DataCall:\tSubmitting Cancel Dial command for Data call")); |
|
1671 iDialData->CancelCommand(aTsyReqHandle); |
|
1672 return KErrNone; |
|
1673 } |
|
1674 |
|
1675 |
|
1676 void CCallMobileData::SetDataCallParams(const TDesC8* aCallParams) |
|
1677 /** |
|
1678 * Utility function which unpacks the call parameters supplied by the client |
|
1679 * and saves their values in iPhoneGlobals. |
|
1680 * If the client did not supply parameters then default ones are used. |
|
1681 */ |
|
1682 { |
|
1683 if(aCallParams->Length()==0) |
|
1684 { |
|
1685 // |
|
1686 // Client did not supply parameters, so we use default ones |
|
1687 LOGTEXT(_L8("CCallMobileData::SetDataCallParams Using default parameters")); |
|
1688 CCallHayes::SetCallParams(aCallParams); |
|
1689 |
|
1690 // |
|
1691 // Ensure the speed parameter is undefined so that we prevent the |
|
1692 // +CBST=... command being sent to the phone when dialling a CSD data call. |
|
1693 iCallInfo.iCallParams.iService = RMobileCall::EServiceUnspecified; |
|
1694 } |
|
1695 else |
|
1696 { |
|
1697 // |
|
1698 // Use call parameters that client supplied us |
|
1699 LOGTEXT(_L8("CCallMobileData::SetDataCallParams Using clients parameters")); |
|
1700 RCall::TCallParamsPckg* paramsPckgV1 = (RCall::TCallParamsPckg*)aCallParams; |
|
1701 RCall::TCallParams& paramsV1 = (*paramsPckgV1)(); |
|
1702 |
|
1703 CCallHayes::SetCallParams(aCallParams); |
|
1704 if (paramsV1.ExtensionId()==RMobileCall::KETelMobileCallParamsV1) |
|
1705 { |
|
1706 RMobileCall::TMobileCallParamsV1Pckg* mmParamsPckgV1 = (RMobileCall::TMobileCallParamsV1Pckg*)aCallParams; |
|
1707 RMobileCall::TMobileCallParamsV1& mmParamsV1 = (*mmParamsPckgV1)(); |
|
1708 iCallInfo.iCallParams.iIdRestrict = mmParamsV1.iIdRestrict; |
|
1709 iCallInfo.iCallParams.iCug = mmParamsV1.iCug; |
|
1710 iCallInfo.iCallParams.iAutoRedial = mmParamsV1.iAutoRedial; |
|
1711 } |
|
1712 |
|
1713 if((paramsV1.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1) || |
|
1714 (paramsV1.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)) |
|
1715 { |
|
1716 RMobileCall::TMobileDataCallParamsV1Pckg* dataParamsPckgV1 = (RMobileCall::TMobileDataCallParamsV1Pckg*)aCallParams; |
|
1717 RMobileCall::TMobileDataCallParamsV1& dataParamsV1 = (*dataParamsPckgV1)(); |
|
1718 iCallInfo.iCallParams.iService=dataParamsV1.iService; |
|
1719 iCallInfo.iCallParams.iSpeed=dataParamsV1.iSpeed; |
|
1720 iCallInfo.iCallParams.iProtocol=dataParamsV1.iProtocol; |
|
1721 iCallInfo.iCallParams.iQoS=dataParamsV1.iQoS; |
|
1722 iCallInfo.iCallParams.iRLPVersion=dataParamsV1.iRLPVersion; |
|
1723 iCallInfo.iCallParams.iModemToMSWindowSize=dataParamsV1.iModemToMSWindowSize; |
|
1724 iCallInfo.iCallParams.iMSToModemWindowSize=dataParamsV1.iMSToModemWindowSize; |
|
1725 iCallInfo.iCallParams.iAckTimer=dataParamsV1.iAckTimer; |
|
1726 iCallInfo.iCallParams.iRetransmissionAttempts=dataParamsV1.iRetransmissionAttempts; |
|
1727 iCallInfo.iCallParams.iResequencingPeriod=dataParamsV1.iResequencingPeriod; |
|
1728 iCallInfo.iCallParams.iV42bisReq=dataParamsV1.iV42bisReq; |
|
1729 iCallInfo.iCallParams.iV42bisCodewordsNum=dataParamsV1.iV42bisCodewordsNum; |
|
1730 iCallInfo.iCallParams.iV42bisMaxStringLength=dataParamsV1.iV42bisMaxStringLength; |
|
1731 } |
|
1732 |
|
1733 if (paramsV1.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1) |
|
1734 { |
|
1735 RMobileCall::TMobileHscsdCallParamsV1Pckg* hscsdParamsPckgV1 = (RMobileCall::TMobileHscsdCallParamsV1Pckg*)aCallParams; |
|
1736 RMobileCall::TMobileHscsdCallParamsV1& hscsdParamsV1 = (*hscsdParamsPckgV1)(); |
|
1737 iCallInfo.iCallParams.iWantedAiur = hscsdParamsV1.iWantedAiur; |
|
1738 iCallInfo.iCallParams.iWantedRxTimeSlots = hscsdParamsV1.iWantedRxTimeSlots; |
|
1739 iCallInfo.iCallParams.iMaxTimeSlots = hscsdParamsV1.iMaxTimeSlots; |
|
1740 iCallInfo.iCallParams.iCodings = hscsdParamsV1.iCodings; |
|
1741 iCallInfo.iCallParams.iAsymmetry = hscsdParamsV1.iAsymmetry; |
|
1742 iCallInfo.iCallParams.iUserInitUpgrade = hscsdParamsV1.iUserInitUpgrade; |
|
1743 } |
|
1744 } |
|
1745 } |
|
1746 |
|
1747 TInt CCallMobileData::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams) |
|
1748 /** |
|
1749 * If there is no waiting call, will wait for one and then answer it. |
|
1750 * If there is a waiting call, will answer immediatly. |
|
1751 * Regardless of if there is a waiting call or not, the +CBST= command is sent immediatly. |
|
1752 */ |
|
1753 { |
|
1754 const CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle); |
|
1755 TInt ret=KErrNone; |
|
1756 if (owned==CCallBase::EOwnedFalse) // call owned by another client |
|
1757 { |
|
1758 ret=KErrEtelNotCallOwner; |
|
1759 } |
|
1760 else |
|
1761 { |
|
1762 if (!iIsForIncomingCall) |
|
1763 { |
|
1764 if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) |
|
1765 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1766 } |
|
1767 else |
|
1768 ret=KErrEtelAnswerAlreadyOutstanding; |
|
1769 } |
|
1770 |
|
1771 if (ret==KErrNone) |
|
1772 { |
|
1773 CLineHayes* line = STATIC_CAST(CLineHayes*,Owner()); |
|
1774 STATIC_CAST(CPhoneHayes*,line->Owner())->CancelOtherRingingCall(line); |
|
1775 line->FreePreAllocCallIfNecessary(); |
|
1776 SetDataCallParams(aCallParams); |
|
1777 if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging) |
|
1778 { |
|
1779 (void)SetOwnership(aTsyReqHandle); |
|
1780 LOGTEXT(_L8("DataCall:\tSubmitting Answer command")); |
|
1781 |
|
1782 // Start the 'send CBST to phone' AT machine and pass the |
|
1783 // CATAnswerData object, so that the call is answered after |
|
1784 // the CBST is sent. |
|
1785 iSetCBST->ExecuteCommand(aTsyReqHandle,iAnswerData,&iCallInfo); |
|
1786 } |
|
1787 else // This call is now a client-designated Incoming Call object. |
|
1788 { |
|
1789 iIsForIncomingCall=ETrue; |
|
1790 iAnswerTsyReqHandle = aTsyReqHandle; |
|
1791 |
|
1792 // Start the 'send CBST to phone' AT machine. This state machine |
|
1793 // will not complete any client request. |
|
1794 iSetCBST->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
1795 } |
|
1796 return KErrNone; |
|
1797 } |
|
1798 |
|
1799 ReqCompleted(aTsyReqHandle,ret); |
|
1800 return KErrNone; |
|
1801 } |
|
1802 |
|
1803 |
|
1804 TInt CCallMobileData::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle) |
|
1805 { |
|
1806 LOGTEXT(_L8("DataCall:\tSubmitting Cancel Answer command")); |
|
1807 if (iIsForIncomingCall) |
|
1808 { |
|
1809 iIsForIncomingCall=EFalse; |
|
1810 ReqCompleted(aTsyReqHandle,KErrCancel); |
|
1811 } |
|
1812 else |
|
1813 iAnswerData->CancelCommand(aTsyReqHandle); |
|
1814 return KErrNone; |
|
1815 } |
|
1816 |
|
1817 void CCallMobileData::AnswerImmediately() |
|
1818 { |
|
1819 (void)SetOwnership(iAnswerTsyReqHandle); |
|
1820 // EStatusRinging always results in KErrNone return |
|
1821 (void) ChangeCallStatus(RMobileCall::EStatusRinging); // new 14/1/99 |
|
1822 iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred); |
|
1823 iIsForIncomingCall=EFalse; // this must be after the check notification as CNotifications |
|
1824 // asks line for info about the call which Is For Incoming Call |
|
1825 LOGTEXT(_L8("DataCall:\tSubmitting Answer command")); |
|
1826 iAnswerData->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo); |
|
1827 } |
|
1828 |
|
1829 TInt CCallMobileData::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams) |
|
1830 // |
|
1831 // Connect to an already dialled call |
|
1832 // |
|
1833 { |
|
1834 TInt ret = ValidateRequest(aTsyReqHandle,RCall::EStatusIdle); |
|
1835 if (ret==KErrNone) |
|
1836 { |
|
1837 (void)SetOwnership(aTsyReqHandle); |
|
1838 SetCallParams(aCallParams); |
|
1839 LOGTEXT(_L8("DataCall:\tSubmitting Immediate Connect command")); |
|
1840 iConnectData->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
1841 } |
|
1842 else |
|
1843 ReqCompleted(aTsyReqHandle,ret); |
|
1844 return KErrNone; |
|
1845 } |
|
1846 |
|
1847 TInt CCallMobileData::ConnectCancel(const TTsyReqHandle aTsyReqHandle) |
|
1848 // |
|
1849 // Cancel immediate connect command |
|
1850 // |
|
1851 { |
|
1852 LOGTEXT(_L8("DataCall:\tSubmitting Cancel Connect command")); |
|
1853 iConnectData->CancelCommand(aTsyReqHandle); |
|
1854 return KErrNone; |
|
1855 } |
|
1856 |
|
1857 TInt CCallMobileData::HangUp(const TTsyReqHandle aTsyReqHandle) |
|
1858 // |
|
1859 // Terminate a data call. If someone else owns call complete with error, but if no-one owns |
|
1860 // it send an ATH anyway, as the connection may have failed and the user wants to ensure |
|
1861 // call has hung up. Call Start() instead of ExecuteCommand() because there is no need to |
|
1862 // initialise before doing this or to send the escape sequence - the hang up sequence drops |
|
1863 // DTR anyway. |
|
1864 // |
|
1865 { |
|
1866 if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse) |
|
1867 { |
|
1868 ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner); |
|
1869 return KErrNone; |
|
1870 } |
|
1871 if ((iCallInfo.iMobileStatus!=RMobileCall::EStatusIdle) && |
|
1872 (iCallInfo.iMobileStatus!=RMobileCall::EStatusDisconnecting)) |
|
1873 { |
|
1874 LOGTEXT(_L8("DataCall:\tSubmitting Hang Up command")); |
|
1875 iHangUpData->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
1876 return KErrNone; |
|
1877 } |
|
1878 else |
|
1879 { |
|
1880 // Call not in a state to be terminated - but return KErrNone |
|
1881 ReqCompleted(aTsyReqHandle,KErrNone); |
|
1882 return KErrNone; |
|
1883 } |
|
1884 } |
|
1885 |
|
1886 TInt CCallMobileData::HangUpCancel(const TTsyReqHandle aTsyReqHandle) |
|
1887 // |
|
1888 // Cancel the hang up command. |
|
1889 // |
|
1890 { |
|
1891 LOGTEXT(_L8("DataCall:\tSubmitting Cancel Hang Up command")); |
|
1892 iHangUpData->Stop(aTsyReqHandle); |
|
1893 return KErrNone; |
|
1894 } |
|
1895 |
|
1896 TInt CCallMobileData::RelinquishOwnership() |
|
1897 // |
|
1898 // Called by server to tell TSY to either pass ownership on to another interested client |
|
1899 // or hang up immediately. If call is currently connecting, RelinquishOwnershipComplete |
|
1900 // will be called once cancelling has finished. |
|
1901 // |
|
1902 { |
|
1903 LOGTEXT(_L8("DataCall:\tRelinquish Ownership")); |
|
1904 if(iList->iAcquireList.IsEmpty()) |
|
1905 { |
|
1906 if (iDialData->IsPreConnectInProgress() || |
|
1907 iConnectData->IsPreConnectInProgress() || |
|
1908 iAnswerData->IsPreConnectInProgress()) |
|
1909 { |
|
1910 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1911 return KErrNone; |
|
1912 } |
|
1913 switch(iCallInfo.iMobileStatus) |
|
1914 { |
|
1915 case RMobileCall::EStatusConnected: |
|
1916 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1917 //iHangUpData->ExecuteCommand(0,NULL,&iCallInfo); |
|
1918 iQuickInit->CancelAndHangUp(&iCallInfo,iHangUpData); |
|
1919 break; |
|
1920 case RMobileCall::EStatusDialling: |
|
1921 case RMobileCall::EStatusConnecting: |
|
1922 case RMobileCall::EStatusAnswering: |
|
1923 case RMobileCall::EStatusDisconnecting: |
|
1924 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1925 break; |
|
1926 default: |
|
1927 if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneInitialising) |
|
1928 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
1929 else |
|
1930 RelinquishOwnershipCompleted(KErrNone); |
|
1931 break; |
|
1932 } |
|
1933 return KErrNone; |
|
1934 } |
|
1935 CAcquireEntry* entry=iList->iAcquireList.First(); |
|
1936 if (entry) |
|
1937 { |
|
1938 (void)SetOwnership(entry->iTsyReqHandle); |
|
1939 ReqCompleted(entry->iTsyReqHandle,KErrNone); |
|
1940 iList->Remove(entry); |
|
1941 } |
|
1942 RelinquishOwnershipCompleted(KErrNone); |
|
1943 return KErrNone; |
|
1944 } |
|
1945 |
|
1946 TInt CCallMobileData::RecoverDataPortAndRelinquishOwnership() |
|
1947 // |
|
1948 // Called by server to tell TSY to either pass ownership on to another interested client |
|
1949 // after regaining control of the port and performing a swift initialisation, |
|
1950 // or hang up immediately |
|
1951 // |
|
1952 { |
|
1953 LOGTEXT(_L8("DataPort Recover and Relinquish Ownership")); |
|
1954 iCallInfo.iLoanedToClient=EFalse; |
|
1955 iPhoneGlobals->iPhoneStatus.iDataPortLoaned = EFalse; |
|
1956 if(iList->iAcquireList.IsEmpty()) |
|
1957 { |
|
1958 (void)SetUnowned(); |
|
1959 iCallInfo.iClientPanicOccurred = EPanicOccurredDuringDataPortLoan; |
|
1960 iIo->Read(); |
|
1961 iHangUpData->ExecuteCommand(0,NULL,&iCallInfo); |
|
1962 return KErrNone; |
|
1963 } |
|
1964 CAcquireEntry* entry=iList->iAcquireList.First(); |
|
1965 if (entry) |
|
1966 { |
|
1967 (void)SetOwnership(entry->iTsyReqHandle); |
|
1968 ReqCompleted(entry->iTsyReqHandle,KErrNone); |
|
1969 iList->Remove(entry); |
|
1970 iQuickInit->StartQuickInit(); |
|
1971 } |
|
1972 RecoverDataPortAndRelinquishOwnershipCompleted(KErrNone); |
|
1973 return KErrNone; |
|
1974 } |
|
1975 |
|
1976 TInt CCallMobileData::LoanDataPort(const TTsyReqHandle aTsyReqHandle, RCall::TCommPort* aCommPort) |
|
1977 // |
|
1978 // Get the port info |
|
1979 // |
|
1980 { |
|
1981 LOGTEXT(_L8(" DataPort Loan")); |
|
1982 if (CheckOwnership(aTsyReqHandle)!=CCallBase::EOwnedTrue) |
|
1983 { |
|
1984 ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner); |
|
1985 return KErrNone; |
|
1986 } |
|
1987 if (iCallInfo.iMobileStatus != RMobileCall::EStatusConnected) |
|
1988 { |
|
1989 ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive); |
|
1990 return KErrNone; |
|
1991 } |
|
1992 TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameCsyName),aCommPort->iCsy); |
|
1993 if (!ret) |
|
1994 { |
|
1995 ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNamePortName),aCommPort->iPort); |
|
1996 } |
|
1997 if (ret) |
|
1998 { |
|
1999 ReqCompleted(aTsyReqHandle,ret); |
|
2000 return KErrNone; |
|
2001 } |
|
2002 iCallInfo.iLoanedToClient = ETrue; |
|
2003 iPhoneGlobals->iPhoneStatus.iDataPortLoaned = ETrue; |
|
2004 iPhoneGlobals->iNotificationStore->CheckNotification(this,EDataPortLoaned); |
|
2005 iWaitForNoCarrier->StopWait(); |
|
2006 if (iPhoneGlobals->iPhoneStatus.iMode==RPhone::EModeOnlineCommand) |
|
2007 iATSetToOnlineDataMode->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
2008 else |
|
2009 { |
|
2010 iIo->Cancel(); |
|
2011 TCommConfig aConfigPckg; |
|
2012 TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeFull); |
|
2013 if (ret==KErrNone) |
|
2014 ret = iIo->ConfigurePort(aConfigPckg); |
|
2015 ReqCompleted(aTsyReqHandle,ret); |
|
2016 } |
|
2017 return KErrNone; |
|
2018 } |
|
2019 |
|
2020 TInt CCallMobileData::LoanDataPortCancel(const TTsyReqHandle aTsyReqHandle) |
|
2021 { |
|
2022 iATSetToOnlineDataMode->CancelCommand(aTsyReqHandle); |
|
2023 return KErrNone; |
|
2024 } |
|
2025 |
|
2026 TInt CCallMobileData::RecoverDataPort(const TTsyReqHandle aTsyReqHandle) |
|
2027 // |
|
2028 // Take back control of data port |
|
2029 // Check that call had been loaned to client |
|
2030 // |
|
2031 { |
|
2032 if (iCallInfo.iLoanedToClient==EFalse) |
|
2033 { |
|
2034 ReqCompleted(aTsyReqHandle,KErrEtelPortNotLoanedToClient); |
|
2035 return KErrNone; |
|
2036 } |
|
2037 TCallOwnership owner = CheckOwnership(aTsyReqHandle); |
|
2038 if (owner!=CCallBase::EOwnedTrue && owner!=CCallBase::EOwnedPriorityClient) |
|
2039 { |
|
2040 ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner); |
|
2041 return KErrNone; |
|
2042 } |
|
2043 LOGTEXT(_L8("DataPort Recover")); |
|
2044 iCallInfo.iLoanedToClient=EFalse; |
|
2045 iPhoneGlobals->iPhoneStatus.iDataPortLoaned = EFalse; |
|
2046 LOGTEXT2(_L8("Comm signals : %x"),iIo->Signals()); |
|
2047 iIo->ResetReadAndWriteBuffers(); // in case client has left RxBuffer non-empty |
|
2048 LOGTEXT2(_L8("Comm signals after ResetBuffers : %x"),iIo->Signals()); |
|
2049 FlowControlSuspend(); // Defect fix for MPO-4ZECUN |
|
2050 iQuickInit->StartQuickInit(); |
|
2051 ReqCompleted(aTsyReqHandle,KErrNone); |
|
2052 return KErrNone; |
|
2053 } |
|
2054 |
|
2055 // local function needed below |
|
2056 |
|
2057 LOCAL_C void SetFaxSessionSettings(RCall::TFaxSessionSettings& aTrg, const RCall::TFaxSessionSettings& aSrc) |
|
2058 { |
|
2059 aTrg.iMode=aSrc.iMode; |
|
2060 aTrg.iFaxRetrieveType=aSrc.iFaxRetrieveType; |
|
2061 aTrg.iFaxClass=aSrc.iFaxClass; |
|
2062 aTrg.iFaxId=aSrc.iFaxId; |
|
2063 aTrg.iMaxSpeed=aSrc.iMaxSpeed; |
|
2064 aTrg.iMinSpeed=aSrc.iMinSpeed; |
|
2065 aTrg.iPreferredECM=aSrc.iPreferredECM; |
|
2066 aTrg.iFaxOnDemandDelay=aSrc.iFaxOnDemandDelay; |
|
2067 aTrg.iTxResolution=aSrc.iTxResolution; |
|
2068 aTrg.iTxCompression=aSrc.iTxCompression; |
|
2069 aTrg.iTxPages=aSrc.iTxPages; |
|
2070 aTrg.iRxResolution=aSrc.iRxResolution; |
|
2071 aTrg.iRxResolution=aSrc.iRxResolution; |
|
2072 } |
|
2073 |
|
2074 // |
|
2075 // CCallMobileFax - fax call functionality |
|
2076 // At construction, phone init sequence may not have yet determined phone's capabilities so |
|
2077 // create object anyway and check in the function calls whether fax is supported by phone |
|
2078 // |
|
2079 |
|
2080 CCallMobileFax* CCallMobileFax::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName) |
|
2081 { |
|
2082 CCallMobileFax* faxCall=new(ELeave) CCallMobileFax(aATIO,aInit,aPhoneGlobals); |
|
2083 TCleanupItem newCallFaxHayesClose(CloseCall,faxCall); |
|
2084 CleanupStack::PushL(newCallFaxHayesClose); |
|
2085 faxCall->ConstructL(aName); |
|
2086 CleanupStack::Pop(); |
|
2087 return faxCall; |
|
2088 } |
|
2089 |
|
2090 CCallMobileFax::CCallMobileFax(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
2091 : CCallMobile(aATIO,aInit,aPhoneGlobals),iFaxSession(NULL),iFax(NULL) |
|
2092 {} |
|
2093 |
|
2094 void CCallMobileFax::ConstructL(const TName& aName) |
|
2095 { |
|
2096 CCallHayes::ConstructL(aName); |
|
2097 iCallInfo.iLineOwnerName = KFaxLineName; |
|
2098 iDialFax=CATDialFax::NewL(iIo,this,iInit,iPhoneGlobals); |
|
2099 iConnectFax=CATConnectFax::NewL(iIo,this,iInit,iPhoneGlobals); |
|
2100 iAnswerFax=CATAnswerFax::NewL(iIo,this,iInit,iPhoneGlobals); |
|
2101 iHangUpFax=CATHangUpFax::NewL(iIo,this,iInit,iPhoneGlobals); |
|
2102 iFaxSettings.iMode = RCall::ETransmit; |
|
2103 iFaxSettings.iFaxRetrieveType = RCall::EFaxOnDemand; |
|
2104 iFaxSettings.iFaxClass = EClassAuto; |
|
2105 iFaxSettings.iMaxSpeed = 9600; |
|
2106 iFaxSettings.iMinSpeed = 2400; |
|
2107 iFaxSettings.iPreferredECM = EFalse; |
|
2108 iFaxSettings.iFaxOnDemandDelay = 20; |
|
2109 iFaxSettings.iTxResolution = EFaxNormal; |
|
2110 iFaxSettings.iTxCompression = EModifiedHuffman; |
|
2111 iFaxSettings.iTxPages = 0; |
|
2112 iFaxSettings.iRxResolution = EFaxNormal; |
|
2113 iFaxSettings.iRxCompression = EModifiedHuffman; |
|
2114 iFaxCompletion = new (ELeave) CFaxCompletion(); |
|
2115 iFaxProgress=CreateFaxProgressChunk(); |
|
2116 if(iFaxProgress==NULL) |
|
2117 User::Leave(KErrEtelFaxChunkNotCreated); |
|
2118 } |
|
2119 |
|
2120 CCallMobileFax::~CCallMobileFax() |
|
2121 // |
|
2122 // Removes itself from array of calls in CLineMobileData |
|
2123 // |
|
2124 { |
|
2125 __ASSERT_DEBUG(iFaxSession==NULL,Panic(EFaxServerNotNull)); |
|
2126 DeleteFaxProgressChunk(); // This deallocates the memory pointed to by iFaxProgress |
|
2127 delete iDialFax; |
|
2128 delete iConnectFax; |
|
2129 delete iAnswerFax; |
|
2130 delete iHangUpFax; |
|
2131 delete iFaxCompletion; |
|
2132 delete iFileHandles; |
|
2133 } |
|
2134 |
|
2135 void CCallMobileFax::CollateCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps) |
|
2136 { |
|
2137 *aCallCaps = RCall::KCapsFax; |
|
2138 if (ValidateFaxClass(iFaxSettings.iFaxClass)==KErrNone |
|
2139 && (!(REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened==TRUE && iFax==NULL)) |
|
2140 && iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent) |
|
2141 // check that fax class is OK and that no other fax call has opened a fax object |
|
2142 { |
|
2143 TCallOwnership owner = CheckOwnership(aTsyReqHandle); |
|
2144 if (ValidateRequest(aTsyReqHandle,RCall::EStatusIdle)==KErrNone) |
|
2145 *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect); |
|
2146 TInt ret=KErrNone; |
|
2147 if (owner==CCallBase::EOwnedFalse) // call owned by another client |
|
2148 ret=KErrEtelNotCallOwner; |
|
2149 else |
|
2150 { |
|
2151 if (!iIsForIncomingCall) |
|
2152 { |
|
2153 if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) |
|
2154 ret=KErrEtelAnswerAlreadyOutstanding; |
|
2155 } |
|
2156 else |
|
2157 ret=KErrEtelAnswerAlreadyOutstanding; |
|
2158 } |
|
2159 if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)) |
|
2160 *aCallCaps |= RCall::KCapsAnswer; |
|
2161 if (owner==CCallBase::EOwnedTrue && iCallInfo.iMobileStatus==RMobileCall::EStatusConnected) |
|
2162 { |
|
2163 *aCallCaps |= RCall::KCapsHangUp; |
|
2164 } |
|
2165 } |
|
2166 } |
|
2167 |
|
2168 TInt CCallMobileFax::OpenFax(TDesC* aTelNumber,TFaxMode aFaxMode) |
|
2169 // |
|
2170 // Open CETelFaxHayes object with desired settings |
|
2171 // |
|
2172 { |
|
2173 TFaxServerSessionSettings faxSettings; |
|
2174 faxSettings.iPhoneNumber.Copy(*aTelNumber); |
|
2175 faxSettings.iLogging = ETrue; |
|
2176 TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameFaxInitString),faxSettings.iFaxInitString); |
|
2177 if (!ret) |
|
2178 { |
|
2179 ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameCsyName),faxSettings.iPortDriverName); |
|
2180 } |
|
2181 if (!ret) |
|
2182 { |
|
2183 ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNamePortName),faxSettings.iCommPortName); |
|
2184 } |
|
2185 if (ret) |
|
2186 return ret; |
|
2187 if(faxSettings.iFaxInitString.Length()==0) |
|
2188 faxSettings.iFaxInitString=KAT2Command; |
|
2189 faxSettings.iMode = aFaxMode; |
|
2190 faxSettings.iFaxClass = iFaxSettings.iFaxClass; |
|
2191 faxSettings.iFaxId = iFaxSettings.iFaxId; |
|
2192 faxSettings.iMaxSpeed = iFaxSettings.iMaxSpeed; |
|
2193 faxSettings.iMinSpeed = iFaxSettings.iMinSpeed; |
|
2194 faxSettings.iPreferredECM = iFaxSettings.iPreferredECM; |
|
2195 faxSettings.iFaxOnDemandDelay = iFaxSettings.iFaxOnDemandDelay; |
|
2196 faxSettings.iTxResolution = iFaxSettings.iTxResolution; |
|
2197 faxSettings.iTxCompression = iFaxSettings.iTxCompression; |
|
2198 faxSettings.iTxPages = iFaxSettings.iTxPages; |
|
2199 faxSettings.iRxResolution = iFaxSettings.iRxResolution; |
|
2200 faxSettings.iRxCompression = iFaxSettings.iRxCompression; |
|
2201 return iFaxSession->FxOpen(faxSettings,iFaxProgress); |
|
2202 } |
|
2203 |
|
2204 TInt CCallMobileFax::ValidateFaxClass(TFaxClass& aFaxClass) |
|
2205 { |
|
2206 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & KFaxCaps) == 0) |
|
2207 { |
|
2208 return KErrNotSupported; |
|
2209 } |
|
2210 switch (aFaxClass) |
|
2211 { |
|
2212 case EClassAuto: // TSY decides what class "AUTO" refers to! |
|
2213 { |
|
2214 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwoPointZero)) |
|
2215 aFaxClass = EClass2point0; |
|
2216 else if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwo)) |
|
2217 aFaxClass = EClass2; |
|
2218 else if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassOne)) |
|
2219 aFaxClass = EClass1; |
|
2220 break; |
|
2221 } |
|
2222 case EClass1: |
|
2223 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassOne)==0) |
|
2224 return KErrEtelWrongModemType; |
|
2225 break; |
|
2226 case EClass1point0: |
|
2227 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassOnePointZero)==0) |
|
2228 return KErrEtelWrongModemType; |
|
2229 break; |
|
2230 case EClass2: |
|
2231 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwo)==0) |
|
2232 return KErrEtelWrongModemType; |
|
2233 break; |
|
2234 case EClass2point0: |
|
2235 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwoPointZero)==0) |
|
2236 return KErrEtelWrongModemType; |
|
2237 break; |
|
2238 case EClass2point1: |
|
2239 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwoPointOne)==0) |
|
2240 return KErrEtelWrongModemType; |
|
2241 break; |
|
2242 default: |
|
2243 return KErrEtelWrongModemType; |
|
2244 } |
|
2245 return KErrNone; |
|
2246 } |
|
2247 |
|
2248 typedef CFaxSession* (*TFaxServerEntry)(); |
|
2249 void CCallMobileFax::GetFaxBaseL() |
|
2250 { |
|
2251 __ASSERT_DEBUG(iFaxCompletion,Panic(EFaxCompletionPtrNull)); |
|
2252 RFs fs; |
|
2253 (void)User::LeaveIfError(fs.Connect()); |
|
2254 |
|
2255 TInt r=iFaxServerLib.Load(KFaxServerName); |
|
2256 if (r==KErrNone) |
|
2257 { |
|
2258 // Check the Uid2 |
|
2259 #if defined (_UNICODE) |
|
2260 if(iFaxServerLib.Type()[1]!=TUid::Uid(KUidUnicodeDynamicFaxServer)) |
|
2261 r = KErrBadLibraryEntryPoint; |
|
2262 #else |
|
2263 if(iFaxServerLib.Type()[1]!=TUid::Uid(KUidDynamicFaxServer)) |
|
2264 r = KErrBadLibraryEntryPoint; |
|
2265 #endif |
|
2266 if (r==KErrNone) |
|
2267 { |
|
2268 TFaxServerEntry libEntry=(TFaxServerEntry)iFaxServerLib.Lookup(1); |
|
2269 if (libEntry!=NULL) |
|
2270 { |
|
2271 TRAP(r,iFaxSession=(*libEntry)()); // libEntry may leave. |
|
2272 if (r==KErrNone) |
|
2273 { |
|
2274 LOGTEXT(_L8("Loaded Fax Server")); |
|
2275 iFaxSession->SetCallBack(iFaxCompletion); |
|
2276 } |
|
2277 else |
|
2278 iFaxServerLib.Close(); |
|
2279 } |
|
2280 else |
|
2281 { |
|
2282 r = KErrBadLibraryEntryPoint; |
|
2283 iFaxServerLib.Close(); |
|
2284 } |
|
2285 } |
|
2286 else |
|
2287 iFaxServerLib.Close(); |
|
2288 } |
|
2289 fs.Close(); |
|
2290 (void)User::LeaveIfError(r); |
|
2291 } |
|
2292 |
|
2293 TInt CCallMobileFax::FaxConnectHandler(const TTsyReqHandle aTsyReqHandle) |
|
2294 { |
|
2295 TInt ret = ValidateFaxClass(iFaxSettings.iFaxClass); |
|
2296 if (ret!=KErrNone) |
|
2297 { |
|
2298 (void)SetUnowned(); |
|
2299 ReqCompleted(aTsyReqHandle,ret); |
|
2300 return ret; |
|
2301 } |
|
2302 if (REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened==TRUE && iFax==NULL) |
|
2303 { |
|
2304 (void)SetUnowned(); |
|
2305 ReqCompleted(aTsyReqHandle,KErrEtelNotFaxOwner); |
|
2306 return ret; |
|
2307 } |
|
2308 |
|
2309 TRAPD(res,GetFaxBaseL()); |
|
2310 if (res!=KErrNone) |
|
2311 { |
|
2312 (void)SetUnowned(); |
|
2313 ReqCompleted(aTsyReqHandle,res); |
|
2314 } |
|
2315 iPhoneGlobals->iEventSignalActive = EFalse; |
|
2316 return res; |
|
2317 } |
|
2318 |
|
2319 void CCallMobileFax::FaxDial(const TTsyReqHandle aTsyReqHandle,TDesC* aTelNumber) |
|
2320 // |
|
2321 // Called once any initialising has been done. Checks here that modem supports fax, |
|
2322 // and that no other CCallHayes has opened a fax object |
|
2323 // |
|
2324 { |
|
2325 if (FaxConnectHandler(aTsyReqHandle)!=KErrNone) // ReqCompleted is called inside FaxConnectHandler |
|
2326 // if there is an error |
|
2327 return; |
|
2328 TFaxMode faxMode; |
|
2329 if (iFaxSettings.iMode==RCall::ETransmit) |
|
2330 { |
|
2331 faxMode = EDialAndTransmit; |
|
2332 } |
|
2333 else // we're receiving |
|
2334 { |
|
2335 if (iFaxSettings.iFaxRetrieveType==RCall::EFaxPoll) |
|
2336 faxMode = EDialAndReceivePoll; |
|
2337 else |
|
2338 faxMode = EDialAndReceiveFaxBack; |
|
2339 } |
|
2340 TInt res = OpenFax(aTelNumber,faxMode); |
|
2341 if (res!=KErrNone) // make sure cleaned up. |
|
2342 { |
|
2343 ReqCompleted(aTsyReqHandle,res); |
|
2344 return; |
|
2345 } |
|
2346 ChangeLineStatus(RCall::EStatusDialling); |
|
2347 // EStatusDialling always results in KErrNone return |
|
2348 (void) ChangeCallStatus(RMobileCall::EStatusDialling); |
|
2349 iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunConnecting); |
|
2350 iFaxCompletion->Configure(aTsyReqHandle,this); |
|
2351 iIo->Cancel(); |
|
2352 iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessDenied; // so CATIO won't queue a read |
|
2353 |
|
2354 if (faxMode == EDialAndTransmit) |
|
2355 { |
|
2356 LOGTEXT(_L8("About to call CETelFaxBase::TxConnect")); |
|
2357 //this transfers ownership of the file handles object to the fax session object. |
|
2358 iFaxSession->SetFaxHeaderFile(iFileHandles); |
|
2359 //we now aren't resonsible for its deletion. |
|
2360 iFileHandles = NULL; |
|
2361 iFaxSession->TxConnect(); |
|
2362 } |
|
2363 else |
|
2364 { |
|
2365 LOGTEXT(_L8("About to call CETelFaxBase::RxConnect")); |
|
2366 iFaxSession->RxConnect(); |
|
2367 } |
|
2368 } |
|
2369 |
|
2370 TInt CCallMobileFax::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber) |
|
2371 // |
|
2372 // Dial a fax call |
|
2373 // Check that call is not owned by another client, and line is idle |
|
2374 // |
|
2375 { |
|
2376 TInt ret = ValidateRequest(aTsyReqHandle,RCall::EStatusIdle); |
|
2377 if (ret==KErrNone) |
|
2378 { |
|
2379 (void)SetOwnership(aTsyReqHandle); |
|
2380 SetCallParams(aCallParams); |
|
2381 LOGTEXT(_L8("FaxCall:\tSubmitting Dial Command")); |
|
2382 iDialFax->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo); |
|
2383 } |
|
2384 else |
|
2385 ReqCompleted(aTsyReqHandle,ret); |
|
2386 return KErrNone; |
|
2387 } |
|
2388 |
|
2389 void CCallMobileFax::FaxCancelCommand(const TTsyReqHandle aTsyReqHandle) |
|
2390 // |
|
2391 // Cancels the fax session (for ConnectCancel and AnswerCancel as well) |
|
2392 // |
|
2393 { |
|
2394 LOGTEXT(_L8("FaxCall:\tCancel Fax call and Unload module")); |
|
2395 if(!iFaxSession) // if iFaxSession is NULL |
|
2396 { // then CleanUpFaxServer has already been called |
|
2397 LOGTEXT(_L8("FaxCall:\tModule already unloaded, completing...")); |
|
2398 ReqCompleted(aTsyReqHandle,KErrCancel); // so return without further processing |
|
2399 return; |
|
2400 } |
|
2401 |
|
2402 LOGTEXT(_L8("FaxCall:\tClosing down fax server module")); |
|
2403 iFaxSession->Cancel(); |
|
2404 CleanUpFaxServer(); |
|
2405 iIo->Read(); |
|
2406 SetToIdle(); |
|
2407 ReqCompleted(aTsyReqHandle,KErrCancel); |
|
2408 } |
|
2409 |
|
2410 TInt CCallMobileFax::DialCancel(const TTsyReqHandle aTsyReqHandle) |
|
2411 { |
|
2412 LOGTEXT2(_L8("FaxCall:\tDialCancel(%d) called"),aTsyReqHandle); |
|
2413 iDialFax->CancelCommand(aTsyReqHandle); |
|
2414 return KErrNone; |
|
2415 } |
|
2416 |
|
2417 void CCallMobileFax::FaxConnect(const TTsyReqHandle aTsyReqHandle) |
|
2418 // |
|
2419 // Called once any initialising has been done. Checks here that modem supports fax. |
|
2420 // |
|
2421 { |
|
2422 if (FaxConnectHandler(aTsyReqHandle)!=KErrNone) |
|
2423 return; |
|
2424 TFaxMode faxMode; |
|
2425 if (iFaxSettings.iMode==RCall::ETransmit) |
|
2426 faxMode = EImmediateTransmit; |
|
2427 else |
|
2428 faxMode = EImmediateReceive; |
|
2429 TBuf<1> null; |
|
2430 null.Zero(); |
|
2431 TInt res = OpenFax(&null,faxMode); |
|
2432 if (res!=KErrNone) |
|
2433 { |
|
2434 ReqCompleted(aTsyReqHandle,res); |
|
2435 return; |
|
2436 } |
|
2437 ChangeLineStatus(RCall::EStatusConnecting); |
|
2438 // EStatusConnecting always returns KErrNone |
|
2439 (void)ChangeCallStatus(RMobileCall::EStatusConnecting); |
|
2440 iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunConnecting); |
|
2441 iFaxCompletion->Configure(aTsyReqHandle,this); |
|
2442 iIo->Cancel(); |
|
2443 iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessDenied; // so CATIO won't queue a read |
|
2444 if (faxMode == EImmediateTransmit) |
|
2445 iFaxSession->TxConnect(); |
|
2446 else |
|
2447 iFaxSession->RxConnect(); |
|
2448 } |
|
2449 |
|
2450 TInt CCallMobileFax::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams) |
|
2451 // |
|
2452 // Immediate connect to a fax call |
|
2453 // Check that call is not owned by another client, and line is idle |
|
2454 // |
|
2455 { |
|
2456 TInt ret = ValidateRequest(aTsyReqHandle,RCall::EStatusIdle); |
|
2457 if (ret==KErrNone) |
|
2458 { |
|
2459 (void)SetOwnership(aTsyReqHandle); |
|
2460 SetCallParams(aCallParams); |
|
2461 LOGTEXT(_L8("FaxCall:\tSubmitting Connect Command")); |
|
2462 iConnectFax->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
2463 } |
|
2464 else |
|
2465 ReqCompleted(aTsyReqHandle,ret); |
|
2466 return KErrNone; |
|
2467 } |
|
2468 |
|
2469 TInt CCallMobileFax::ConnectCancel(const TTsyReqHandle aTsyReqHandle) |
|
2470 { |
|
2471 LOGTEXT2(_L8("FaxCall:\tConnectCancel(%d) called"),aTsyReqHandle); |
|
2472 iConnectFax->CancelCommand(aTsyReqHandle); |
|
2473 return KErrNone; |
|
2474 } |
|
2475 |
|
2476 void CCallMobileFax::FaxAnswer(const TTsyReqHandle aTsyReqHandle) |
|
2477 { |
|
2478 if (FaxConnectHandler(aTsyReqHandle)!=KErrNone) |
|
2479 return; |
|
2480 TFaxMode faxMode; |
|
2481 if (iFaxSettings.iMode==RCall::ETransmit) |
|
2482 faxMode = EWaitForRingAndTransmit; |
|
2483 else |
|
2484 faxMode = EWaitForRingAndReceive; |
|
2485 TBuf<1> null; |
|
2486 null.Zero(); |
|
2487 TInt res = OpenFax(&null,faxMode); |
|
2488 if (res!=KErrNone) |
|
2489 { |
|
2490 ReqCompleted(aTsyReqHandle,res); |
|
2491 return; |
|
2492 } |
|
2493 LOGTEXT(_L8("FaxCall:\tAnswering Fax call")); |
|
2494 ChangeLineStatus(RCall::EStatusAnswering); |
|
2495 // EStatusAnswering always results in KerrNone return |
|
2496 (void)ChangeCallStatus(RMobileCall::EStatusAnswering); |
|
2497 CPhoneHayes* phone=STATIC_CAST(CPhoneHayes*,Owner()->Owner()); |
|
2498 phone->StopRingCounter(); // RING should no longer come in |
|
2499 iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunConnecting); |
|
2500 iFaxCompletion->Configure(aTsyReqHandle,this); |
|
2501 iIo->Cancel(); |
|
2502 iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessDenied; // so CATIO won't queue a read |
|
2503 if (faxMode == EWaitForRingAndTransmit) |
|
2504 iFaxSession->TxConnect(); |
|
2505 else |
|
2506 iFaxSession->RxConnect(); |
|
2507 } |
|
2508 |
|
2509 TInt CCallMobileFax::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams) |
|
2510 // |
|
2511 // Answer a fax call |
|
2512 // |
|
2513 { |
|
2514 TInt ret=KErrNone; |
|
2515 CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle); |
|
2516 if (owned==CCallBase::EOwnedFalse) // call owned by another client |
|
2517 { |
|
2518 ret=KErrEtelNotCallOwner; |
|
2519 } |
|
2520 else if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) |
|
2521 ret=KErrEtelAnswerAlreadyOutstanding; |
|
2522 |
|
2523 if (ret==KErrNone) |
|
2524 { |
|
2525 CLineHayes* line = STATIC_CAST(CLineHayes*,Owner()); |
|
2526 CPhoneHayes* phone=STATIC_CAST(CPhoneHayes*,line->Owner()); |
|
2527 phone->CancelOtherRingingCall(line); |
|
2528 line->FreePreAllocCallIfNecessary(); |
|
2529 SetCallParams(aCallParams); |
|
2530 if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging) |
|
2531 { |
|
2532 LOGTEXT(_L8("FaxCall:\tSubmitting Answer Command")); |
|
2533 iAnswerFax->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
2534 } |
|
2535 else // This call is now a client-designated Incoming Call object. |
|
2536 { |
|
2537 iIsForIncomingCall=ETrue; |
|
2538 iAnswerTsyReqHandle = aTsyReqHandle; |
|
2539 } |
|
2540 return KErrNone; |
|
2541 } |
|
2542 ReqCompleted(aTsyReqHandle,ret); |
|
2543 return KErrNone; |
|
2544 } |
|
2545 |
|
2546 TInt CCallMobileFax::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle) |
|
2547 // |
|
2548 // Cancel the answer command if possible |
|
2549 // |
|
2550 { |
|
2551 LOGTEXT2(_L8("FaxCall:\tAnswerCancel(%d) called"),aTsyReqHandle); |
|
2552 if (iIsForIncomingCall) |
|
2553 { |
|
2554 iIsForIncomingCall=EFalse; |
|
2555 ReqCompleted(aTsyReqHandle,KErrCancel); |
|
2556 } |
|
2557 else |
|
2558 iAnswerFax->CancelCommand(aTsyReqHandle); |
|
2559 return KErrNone; |
|
2560 } |
|
2561 |
|
2562 void CCallMobileFax::AnswerImmediately() |
|
2563 { |
|
2564 (void)SetOwnership(iAnswerTsyReqHandle); |
|
2565 // EStatusRinging always results in KErrNone return |
|
2566 (void)ChangeCallStatus(RMobileCall::EStatusRinging);// new 14/1/99 |
|
2567 iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred); |
|
2568 iIsForIncomingCall=EFalse; |
|
2569 LOGTEXT(_L8("FaxCall:\tSubmitting Answer command")); |
|
2570 iAnswerFax->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo); |
|
2571 } |
|
2572 |
|
2573 void CCallMobileFax::FaxHangUp(const TTsyReqHandle aTsyReqHandle) |
|
2574 // |
|
2575 // Fax server reconfigures port so no need to here. |
|
2576 // |
|
2577 { |
|
2578 if (iFaxSession) |
|
2579 { |
|
2580 // EStatusDisconnecting always results in KErrNone return |
|
2581 (void)ChangeCallStatus(RMobileCall::EStatusDisconnecting); |
|
2582 ChangeLineStatus(RCall::EStatusHangingUp); |
|
2583 iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunHangingUp); |
|
2584 CleanUpFaxServer(); |
|
2585 iIo->Read(); |
|
2586 SetToIdle(); |
|
2587 } |
|
2588 ReqCompleted(aTsyReqHandle,KErrNone); |
|
2589 } |
|
2590 |
|
2591 TInt CCallMobileFax::HangUp(const TTsyReqHandle aTsyReqHandle) |
|
2592 // |
|
2593 // Terminate a fax call. Checks fax capability, call ownership and line status. |
|
2594 // |
|
2595 { |
|
2596 if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & KFaxCaps) == 0) |
|
2597 { |
|
2598 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
2599 return KErrNone; |
|
2600 } |
|
2601 if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse) |
|
2602 { |
|
2603 ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner); |
|
2604 return KErrNone; |
|
2605 } |
|
2606 if (iPhoneGlobals->iPhoneStatus.iLineStatus != RCall::EStatusConnected) |
|
2607 { |
|
2608 ReqCompleted(aTsyReqHandle,KErrNone); |
|
2609 return KErrNone; |
|
2610 } |
|
2611 LOGTEXT(_L8("FaxCall:\tHanging up")); |
|
2612 iHangUpFax->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); |
|
2613 return KErrNone; |
|
2614 } |
|
2615 |
|
2616 TInt CCallMobileFax::HangUpCancel(const TTsyReqHandle aTsyReqHandle) |
|
2617 { |
|
2618 iHangUpFax->CancelCommand(aTsyReqHandle); |
|
2619 return KErrNone; |
|
2620 } |
|
2621 |
|
2622 TInt CCallMobileFax::RelinquishOwnership() |
|
2623 // |
|
2624 // Called by server to tell TSY to either pass ownership on to another interested client |
|
2625 // or hang up immediately |
|
2626 // |
|
2627 { |
|
2628 LOGTEXT(_L8("FaxCall:\tRelinquish Ownership")); |
|
2629 if(iList->iAcquireList.IsEmpty()) |
|
2630 { |
|
2631 if (iDialFax->IsPreConnectInProgress() || |
|
2632 iConnectFax->IsPreConnectInProgress() || |
|
2633 iAnswerFax->IsPreConnectInProgress()) // fax server has not yet been started |
|
2634 { |
|
2635 iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; |
|
2636 return KErrNone; |
|
2637 } |
|
2638 (void)SetUnowned(); |
|
2639 TInt ret = KErrNone; |
|
2640 if (iCallInfo.iMobileStatus==RMobileCall::EStatusDialling || |
|
2641 iCallInfo.iMobileStatus==RMobileCall::EStatusConnecting || |
|
2642 iCallInfo.iMobileStatus==RMobileCall::EStatusAnswering || |
|
2643 iCallInfo.iMobileStatus==RMobileCall::EStatusConnected || |
|
2644 iCallInfo.iMobileStatus==RMobileCall::EStatusDisconnecting |
|
2645 ) |
|
2646 { |
|
2647 LOGTEXT(_L8("FaxCall:\tHanging up")); |
|
2648 ChangeLineStatus(RCall::EStatusHangingUp); |
|
2649 // EStatusDisconnecting always results in KErrNone return |
|
2650 (void)ChangeCallStatus(RMobileCall::EStatusDisconnecting); |
|
2651 CleanUpFaxServer(); |
|
2652 ChangeLineStatus(RCall::EStatusIdle); |
|
2653 // EStatusIdle always results in KErrNone return |
|
2654 (void)ChangeCallStatus(RMobileCall::EStatusIdle); |
|
2655 iPhoneGlobals->iPhoneStatus.iMode = RPhone::EModeIdle; |
|
2656 iIo->Cancel(); |
|
2657 TCommConfig aConfigPckg; |
|
2658 TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeInit); |
|
2659 if (ret==KErrNone) |
|
2660 ret = iIo->ConfigurePort(aConfigPckg); |
|
2661 if (ret) |
|
2662 iPhoneGlobals->iPhoneStatus.iInitStatus = EPhoneNotInitialised; |
|
2663 else |
|
2664 iIo->Read(); // should a read be queued in this case? |
|
2665 } |
|
2666 RelinquishOwnershipCompleted(ret); |
|
2667 return KErrNone; |
|
2668 } |
|
2669 CAcquireEntry* entry=iList->iAcquireList.First(); |
|
2670 if (entry) |
|
2671 { |
|
2672 (void)SetOwnership(entry->iTsyReqHandle); |
|
2673 ReqCompleted(entry->iTsyReqHandle,KErrNone); |
|
2674 iList->Remove(entry); |
|
2675 } |
|
2676 RelinquishOwnershipCompleted(KErrNone); |
|
2677 return KErrNone; |
|
2678 } |
|
2679 |
|
2680 TInt CCallMobileFax::GetFaxSettings(const TTsyReqHandle aTsyReqHandle,RCall::TFaxSessionSettings* aSettings) |
|
2681 // |
|
2682 // Which are stored privately in CCallMobileFax |
|
2683 // |
|
2684 { |
|
2685 LOGTEXT(_L8("FaxCall:\tGetting fax settings")); |
|
2686 SetFaxSessionSettings(*aSettings,iFaxSettings); |
|
2687 ReqCompleted(aTsyReqHandle,KErrNone); |
|
2688 return KErrNone; |
|
2689 } |
|
2690 |
|
2691 TInt CCallMobileFax::SetFaxSettings(const TTsyReqHandle aTsyReqHandle,const RCall::TFaxSessionSettings* aSettings) |
|
2692 { |
|
2693 LOGTEXT(_L8("FaxCall:\tSetting fax settings")); |
|
2694 TUint phoneCaps = iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags; |
|
2695 if (aSettings->iFaxClass==EClass1 && (phoneCaps&RPhone::KCapsFaxClassOne) || |
|
2696 aSettings->iFaxClass==EClass2 && (phoneCaps&RPhone::KCapsFaxClassTwo) || |
|
2697 aSettings->iFaxClass==EClass2point0 && (phoneCaps&RPhone::KCapsFaxClassTwoPointZero) || |
|
2698 aSettings->iFaxClass==EClass1point0 && (phoneCaps&RPhone::KCapsFaxClassOnePointZero) || |
|
2699 aSettings->iFaxClass==EClass2point1 && (phoneCaps&RPhone::KCapsFaxClassTwoPointOne) || |
|
2700 aSettings->iFaxClass==EClassAuto) |
|
2701 { |
|
2702 SetFaxSessionSettings(iFaxSettings,*aSettings); |
|
2703 ReqCompleted(aTsyReqHandle,KErrNone); |
|
2704 } |
|
2705 else if (iPhoneGlobals->iPhoneStatus.iInitStatus!=EPhoneInitialised) |
|
2706 ReqCompleted(aTsyReqHandle,KErrEtelUnknownModemCapability); |
|
2707 else |
|
2708 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
2709 return KErrNone; |
|
2710 } |
|
2711 |
|
2712 TInt CCallMobileFax::SetFaxSharedHeaderFile(const TTsyReqHandle aTsyReqHandle, CFaxSharedFileHandles* aFaxSharedFileHandles) |
|
2713 { |
|
2714 //if we already own an object delete and re-point to new one. |
|
2715 if(iFileHandles) |
|
2716 { |
|
2717 delete iFileHandles; |
|
2718 iFileHandles = NULL; |
|
2719 } |
|
2720 iFileHandles = aFaxSharedFileHandles; |
|
2721 |
|
2722 ReqCompleted(aTsyReqHandle,KErrNone); |
|
2723 return KErrNone; |
|
2724 } |
|
2725 |
|
2726 CTelObject* CCallMobileFax::OpenNewObjectByNameL(const TDesC& /*aName*/) |
|
2727 // |
|
2728 // Only want one CFaxHayes object to be opened per phone. |
|
2729 // Previously only the connected call could open a CFaxHayes object, so it was easy to check |
|
2730 // whether one had already been opened. Now a fax call can open a fax object at any time |
|
2731 // making it less clear how to check that no other call has opened one. |
|
2732 // |
|
2733 { |
|
2734 if (iPhoneGlobals->iPhoneStatus.iLineStatus != GetCoreCallStatus()) |
|
2735 { // ie another fax call is in progress so this call cannot open a fax object |
|
2736 User::Leave(KErrEtelNotCallOwner); |
|
2737 } |
|
2738 TBool& faxOpened = REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened; |
|
2739 if (faxOpened==TRUE) |
|
2740 { |
|
2741 User::Leave(KErrAlreadyExists); |
|
2742 } |
|
2743 faxOpened=ETrue; |
|
2744 iFax = CFaxHayes::NewL(this,iPhoneGlobals); |
|
2745 return iFax; |
|
2746 } |
|
2747 |
|
2748 void CCallMobileFax::RemoveFax(CFaxHayes* aFaxHayes) |
|
2749 { |
|
2750 if (iFax == aFaxHayes) |
|
2751 iFax=NULL; |
|
2752 REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened=EFalse; |
|
2753 } |
|
2754 |
|
2755 void CCallMobileFax::CleanUpFaxServer() |
|
2756 { |
|
2757 LOGTEXT(_L8("Closing down Fax Server")); |
|
2758 (void)iFaxSession->FxClose(); |
|
2759 iFaxServerLib.Close(); |
|
2760 iFaxSession = NULL; |
|
2761 iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessAllowed; |
|
2762 iPhoneGlobals->iEventSignalActive = EFalse; |
|
2763 } |