|
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 "PHONE.H" |
|
18 #include "LINE.H" |
|
19 #include "CALL.H" |
|
20 #include "NOTIFY.H" |
|
21 #include "mSLOGGER.H" |
|
22 #include "ATINIT.H" |
|
23 #include "ATERROR.H" |
|
24 #include "mPHBOOK.H" |
|
25 #include "mnetwork.h" |
|
26 #include "ATIO.H" |
|
27 #include "Matstd.h" // for KXXStorage constants |
|
28 #include "et_struct.h" |
|
29 |
|
30 #if defined (__WINS__) |
|
31 _LIT(KPDDName,"ECDRV"); |
|
32 _LIT(KLDDName,"ECOMM"); |
|
33 #else |
|
34 _LIT(KPDDName,"EUART1"); |
|
35 #if defined (PDD2_NAME) |
|
36 _LIT(KPDD2Name,"EUART2"); |
|
37 #endif |
|
38 _LIT(KLDDName,"ECOMM"); |
|
39 #endif |
|
40 |
|
41 |
|
42 // |
|
43 // CPhoneGlobals |
|
44 // |
|
45 CPhoneGlobals* CPhoneGlobals::NewL(TBool aExplicit) |
|
46 { |
|
47 CPhoneGlobals* self = new(ELeave)CPhoneGlobals(); |
|
48 CleanupStack::PushL(self); |
|
49 self->ConstructL(aExplicit); |
|
50 CleanupStack::Pop(); |
|
51 return self; |
|
52 } |
|
53 |
|
54 void CPhoneGlobals::ConstructL(TBool aExplicit) |
|
55 { |
|
56 iPhoneStatus.iModemDetected = RPhone::EDetectedUnknown; |
|
57 iPhoneStatus.iDataAndFaxFlags = RPhone::KCapsUnknown; |
|
58 iPhoneStatus.iWaitForCarrierTime = KDefaultSecondsToWaitForCarrier; |
|
59 iPhoneStatus.iRegistrationStatus = RMobilePhone::ERegistrationUnknown; |
|
60 iConfiguration=CTsyConfig::NewL(aExplicit); |
|
61 iNotificationStore=CNotifications::NewL(); |
|
62 } |
|
63 |
|
64 CPhoneGlobals::~CPhoneGlobals() |
|
65 { |
|
66 delete iConfiguration; |
|
67 delete iNotificationStore; |
|
68 } |
|
69 |
|
70 TBool CPhoneGlobals::IsWriteAccess(TStorageType aStorageType) |
|
71 { |
|
72 if ((aStorageType.Compare(KMEStorage)==KErrNone) || |
|
73 (aStorageType.Compare(KSMStorage)==KErrNone) || |
|
74 (aStorageType.CompareF(KTAStorage)==KErrNone)) |
|
75 return ETrue; |
|
76 else |
|
77 return EFalse; |
|
78 } |
|
79 |
|
80 |
|
81 void CPhoneGlobals::CheckForChangeOfNetwork() |
|
82 // |
|
83 // Changes in network registration may imply a change of operator, which involves issuing |
|
84 // more AT commands. |
|
85 // |
|
86 { |
|
87 if (iATNetworkInfo && iPhoneStatus.iNetworkChanged && |
|
88 ((iPhoneStatus.iMode==RPhone::EModeIdle)|| |
|
89 (iPhoneStatus.iMode==RPhone::EModeOnlineCommand))) |
|
90 { |
|
91 LOGTEXT(_L8("CPhoneGlobals: Update CurrentNetworkInfo")); |
|
92 iATNetworkInfo->CheckOperator(); |
|
93 } |
|
94 } |
|
95 |
|
96 // |
|
97 // Character set conversion between the ME encoding (see +CSCS) and Unicode |
|
98 // |
|
99 // TO DO: Add appropriate use of CHARCONV converters |
|
100 // "GSM" => KCharacterSetIdentifierSms7Bit |
|
101 // "IRA" => KCharacterSetIdentifierAscii |
|
102 // "8859-1" => KCharacterSetISO88591 |
|
103 |
|
104 TInt CPhoneGlobals::ConvertFromUnicode(TDes8& aMEString, const TDesC16& aUnicode) const |
|
105 { |
|
106 aMEString.Copy(aUnicode); |
|
107 return KErrNone; |
|
108 } |
|
109 |
|
110 TInt CPhoneGlobals::ConvertToUnicode(TDes16& aUnicode, const TDesC8& aMEString) const |
|
111 { |
|
112 aUnicode.Copy(aMEString); |
|
113 return KErrNone; |
|
114 } |
|
115 |
|
116 |
|
117 |
|
118 // |
|
119 // CPhoneHayes |
|
120 // |
|
121 void CPhoneHayes::ClosePhone(TAny* aObj) |
|
122 // |
|
123 // Utility func for cleanup stack |
|
124 // |
|
125 { |
|
126 ((CObject*)aObj)->Close(); |
|
127 } |
|
128 |
|
129 CPhoneHayes* CPhoneHayes::NewL() |
|
130 { |
|
131 CPhoneHayes* phone=new(ELeave) CPhoneHayes(); |
|
132 TCleanupItem newPhoneHayesClose(ClosePhone,phone); |
|
133 CleanupStack::PushL(newPhoneHayesClose); |
|
134 phone->ConstructL(); |
|
135 CleanupStack::Pop(); |
|
136 return phone; |
|
137 } |
|
138 |
|
139 void CPhoneHayes::ConstructL() |
|
140 // |
|
141 // Creation of Global Params |
|
142 // |
|
143 { |
|
144 LOGTEXTREL(_L8("---------- New Log ----------")); // Added this to keep log looking like it used to |
|
145 |
|
146 // Add description of component build to log flie |
|
147 #if defined(__WINS__) |
|
148 LOGTEXTREL(_L8("Platform: WINS")); |
|
149 #elif defined(__MARM_ARMI__) |
|
150 LOGTEXTREL(_L8("Platform: ARMI")); |
|
151 #elif defined(__MARM_ARM4__) |
|
152 LOGTEXTREL(_L8("Platform: ARM4")); |
|
153 #elif defined(__MARM_THUMB__) |
|
154 LOGTEXTREL(_L8("Platform: THUMB")); |
|
155 #else |
|
156 LOGTEXTREL(_L8("Platform: unknown")); |
|
157 #endif |
|
158 #if defined (_DEBUG) |
|
159 LOGTEXTREL(_L8("Variant: DEBUG")); |
|
160 #else |
|
161 LOGTEXTREL(_L8("Variant: RELEASE")); |
|
162 #endif |
|
163 |
|
164 LOGTEXT(_L8("--- CPhoneHayes::ConstructL() ---")); |
|
165 |
|
166 LOGTEXT(_L8("Loading Serial drivers")); |
|
167 |
|
168 TInt r=User::LoadPhysicalDevice(KPDDName); |
|
169 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
170 User::Leave(r); |
|
171 #if defined (PDD2_NAME) |
|
172 r=User::LoadPhysicalDevice(KPDD2Name); |
|
173 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
174 User::Leave(r); |
|
175 #endif |
|
176 r=User::LoadLogicalDevice(KLDDName); |
|
177 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
178 User::Leave(r); |
|
179 |
|
180 |
|
181 |
|
182 iDefaultDataLineInfo.iStatus = RCall::EStatusUnknown; |
|
183 iDefaultDataLineInfo.iLineCapsFlags = ( RLine::KCapsData|RLine::KCapsEventIncomingCall); |
|
184 iDefaultDataLineInfo.iName = KDataLineName; |
|
185 iDefaultFaxLineInfo.iStatus = RCall::EStatusUnknown; |
|
186 iDefaultFaxLineInfo.iLineCapsFlags = ( RLine::KCapsFax|RLine::KCapsEventIncomingCall); |
|
187 iDefaultFaxLineInfo.iName = KFaxLineName; |
|
188 iDefaultVoiceLineInfo.iStatus = RCall::EStatusUnknown; |
|
189 iDefaultVoiceLineInfo.iLineCapsFlags = (RLine::KCapsVoice|RLine::KCapsEventIncomingCall); |
|
190 iDefaultVoiceLineInfo.iName = KVoiceLineName; |
|
191 iSizeOfMemberData = new(ELeave) CArrayFixFlat<TInt>(1); |
|
192 } |
|
193 |
|
194 CPhoneHayes::~CPhoneHayes() |
|
195 // |
|
196 // iIo must be deleted after pointers to objects which used it |
|
197 // |
|
198 { |
|
199 LOGTEXT(_L8("Entered CPhoneHayes destructor")); |
|
200 if (iPhoneGlobals != NULL) |
|
201 iPhoneGlobals->iNotificationStore->RemoveClientFromLastEvents(this); |
|
202 delete iInit; |
|
203 delete iErrorHandler; |
|
204 delete iWaitForCall; |
|
205 delete iPhoneGlobals; |
|
206 if (iSizeOfMemberData!=NULL) |
|
207 iSizeOfMemberData->Reset(); |
|
208 delete iSizeOfMemberData; |
|
209 if (iIo!=NULL) |
|
210 { |
|
211 iIo->Cancel(); |
|
212 iIo->Disconnect(); |
|
213 delete iIo; |
|
214 } |
|
215 LOGTEXT(_L8("--- CPhoneHayes::~CPhoneHayes() ---")); |
|
216 } |
|
217 |
|
218 |
|
219 TInt CPhoneHayes::MultimodeInitL(TBool aExplicit) |
|
220 { |
|
221 TFileName csy; |
|
222 TName port; |
|
223 |
|
224 if(!aExplicit && !iPhoneGlobals) |
|
225 { |
|
226 iPhoneGlobals = CPhoneGlobals::NewL(aExplicit); |
|
227 } |
|
228 |
|
229 LOGTEXT(_L8("Getting CSY from CommDB")); |
|
230 (void)User::LeaveIfError(iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameCsyName),csy)); |
|
231 |
|
232 LOGTEXT(_L8("Getting PORT from CommDB")); |
|
233 (void)User::LeaveIfError(iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNamePortName),port)); |
|
234 |
|
235 if(!iIo) |
|
236 iIo=CATIO::NewL(csy,port,iPhoneGlobals->iPhoneStatus.iPortAccess); |
|
237 |
|
238 if(!iWaitForCall) |
|
239 iWaitForCall=CATWaitForCall::NewL(iIo,this,iPhoneGlobals); |
|
240 |
|
241 if(!iErrorHandler) |
|
242 iErrorHandler = CATErrorHandler::NewL(iPhoneGlobals,iWaitForCall); |
|
243 |
|
244 iIo->SetErrorHandler(iErrorHandler); |
|
245 |
|
246 if(!iInit) |
|
247 iInit=CATInit::NewL(iIo,this,iPhoneGlobals); |
|
248 |
|
249 FlowControlSuspend(); |
|
250 iInit->SpecialStart(); |
|
251 |
|
252 return KErrNone; |
|
253 } |
|
254 |
|
255 TInt CPhoneHayes::ExtFunc(const TTsyReqHandle,const TInt, const TDataPackage&) |
|
256 // |
|
257 // Extensions aren't supported in this TSY |
|
258 // |
|
259 { |
|
260 return KErrNotSupported; |
|
261 } |
|
262 |
|
263 TInt CPhoneHayes::CheckAndSetRegistrationParams(const TInt /*aIpc*/,const TDes8* /*aDes1*/,const TDes8* /*aDes2*/) |
|
264 { |
|
265 return KErrNotSupported; |
|
266 } |
|
267 |
|
268 // |
|
269 // Implemented Phone Functions |
|
270 // |
|
271 CTelObject* CPhoneHayes::OpenNewObjectByNameL(const TDesC& aName) |
|
272 // |
|
273 // Open a new line. Opens fax line even if phone does not support it, as that information |
|
274 // may not be available (init sequence may not have reached that far.) |
|
275 // |
|
276 { |
|
277 if (!aName.CompareF(KDataLineName)) |
|
278 { |
|
279 __ASSERT_ALWAYS(iDataLine==NULL,Panic(ELineAlreadyExists)); |
|
280 iDataLine=CLineMobileData::NewL(iIo,iInit,iPhoneGlobals,aName); |
|
281 if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusUnknown) |
|
282 iPhoneGlobals->iPhoneStatus.iLineStatus = RCall::EStatusIdle; |
|
283 return iDataLine; |
|
284 } |
|
285 else if (!aName.CompareF(KFaxLineName)) |
|
286 { |
|
287 __ASSERT_ALWAYS(iFaxLine==NULL,Panic(ELineAlreadyExists)); |
|
288 iFaxLine=CLineMobileFax::NewL(iIo,iInit,iPhoneGlobals,aName); |
|
289 if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusUnknown) |
|
290 iPhoneGlobals->iPhoneStatus.iLineStatus = RCall::EStatusIdle; |
|
291 return iFaxLine; |
|
292 } |
|
293 |
|
294 else if (!aName.CompareF(KVoiceLineName)) //Added for Java Demo 4.4.99 |
|
295 { |
|
296 __ASSERT_ALWAYS(iVoiceLine==NULL,Panic(ELineAlreadyExists)); |
|
297 iVoiceLine=CLineMobileVoice::NewL(iIo,iInit,iPhoneGlobals,aName); |
|
298 if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusUnknown) |
|
299 iPhoneGlobals->iPhoneStatus.iLineStatus = RCall::EStatusIdle; |
|
300 return iVoiceLine; |
|
301 } |
|
302 else |
|
303 { |
|
304 User::Leave(KErrNotFound); |
|
305 return NULL; |
|
306 } |
|
307 } |
|
308 |
|
309 CTelObject* CPhoneHayes::OpenNewObjectL(TDes&) |
|
310 { |
|
311 User::Leave(KErrNotSupported); |
|
312 return NULL; |
|
313 } |
|
314 |
|
315 CTelObject::TReqMode CPhoneHayes::ReqModeL(const TInt aIpc) |
|
316 { |
|
317 TReqMode reqMode = CPhoneBase::ReqModeL(aIpc); |
|
318 if ((reqMode & KReqModeFlowControlObeyed) && iPhoneGlobals->iPhoneStatus.iDataPortLoaned) |
|
319 { |
|
320 LOGTEXT2(_L8("ReqModeL Leaving with KErrInUse as data port is loaned (aIpc=%d)"),aIpc); |
|
321 User::Leave(KErrInUse); |
|
322 } |
|
323 |
|
324 return reqMode; |
|
325 } |
|
326 |
|
327 TInt CPhoneHayes::RegisterNotification(const TInt /*aIpc*/) |
|
328 { |
|
329 return KErrNone; |
|
330 } |
|
331 TInt CPhoneHayes::DeregisterNotification(const TInt /*aIpc*/) |
|
332 { |
|
333 return KErrNone; |
|
334 } |
|
335 |
|
336 void CPhoneHayes::Init() |
|
337 // |
|
338 // Automatic start-up initialise function, doesn't call an AT command on completion |
|
339 // Re-implemented because modem must be initialised before any RING comes in |
|
340 // |
|
341 { |
|
342 } |
|
343 |
|
344 TInt CPhoneHayes::ControlledInitialisation(const TTsyReqHandle aTsyReqHandle) |
|
345 /* |
|
346 * If the phone is already initialised, then there's nothing to do. However, if for some |
|
347 * reason the phone has not been successfully initialised, but the port is not available |
|
348 * (e.g. it may be loaned) then just return KErrAccessDenied. |
|
349 * If none of the cases above apply then proceed with the initialisation as usual. |
|
350 */ |
|
351 { |
|
352 if(iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneInitialised) // This also fixes defect MPO-4ZECUN |
|
353 { |
|
354 LOGTEXT(_L8("CPhoneHayes::ControlledInitialisation\tPhone has been initialised - Completing request.")); |
|
355 ReqCompleted(aTsyReqHandle,KErrNone); |
|
356 return KErrNone; |
|
357 } |
|
358 |
|
359 if(iPhoneGlobals->iPhoneStatus.iPortAccess==EPortAccessDenied) |
|
360 { |
|
361 LOGTEXT(_L8("CPhoneHayes::ControlledInitialisation\tPort Access Denied flag detected")); |
|
362 ReqCompleted(aTsyReqHandle,KErrAccessDenied); |
|
363 return KErrNone; |
|
364 } |
|
365 |
|
366 if(iInit==NULL) |
|
367 { |
|
368 LOGTEXT(_L8("CPhoneHayes::ControlledInitialisation\tPort Access Denied flag detected")); |
|
369 ReqCompleted(aTsyReqHandle,KErrHardwareNotAvailable); |
|
370 return KErrNone; |
|
371 } |
|
372 |
|
373 TInt aError; |
|
374 if (iInit->JustInitialised(aError)) |
|
375 ReqCompleted(aTsyReqHandle,aError); |
|
376 else |
|
377 iInit->SpecialStart(aTsyReqHandle); |
|
378 |
|
379 return KErrNone; |
|
380 } |
|
381 |
|
382 TInt CPhoneHayes::ControlledInitialisationCancel(const TTsyReqHandle aTsyReqHandle) |
|
383 { |
|
384 iInit->StopInit(aTsyReqHandle); |
|
385 return KErrNone; |
|
386 } |
|
387 |
|
388 TInt CPhoneHayes::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RPhone::TCaps* /*aCaps*/) |
|
389 { |
|
390 // iPhoneGlobals->iNotificationStore->RegisterNotification(EPhoneGeneral,aTsyReqHandle,this,aPhoneInfo); |
|
391 ReqCompleted(aTsyReqHandle,KErrNotSupported); |
|
392 return KErrNone; |
|
393 } |
|
394 |
|
395 TInt CPhoneHayes::NotifyCapsChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
396 { |
|
397 // iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
398 ReqCompleted(aTsyReqHandle,KErrCancel); |
|
399 return KErrNone; |
|
400 } |
|
401 |
|
402 TInt CPhoneHayes::NotifyModemDetected(const TTsyReqHandle aTsyReqHandle, RPhone::TModemDetection* aDetection) |
|
403 // |
|
404 // This request will be completed when the phone's connection status changes |
|
405 // |
|
406 { |
|
407 LOGTEXT(_L8("Phone:\tDetection Change Notification lodged")); |
|
408 iPhoneGlobals->iNotificationStore->RegisterNotification(EModemDetection,aTsyReqHandle,this,aDetection); |
|
409 return KErrNone; |
|
410 } |
|
411 |
|
412 TInt CPhoneHayes::NotifyModemDetectedCancel(const TTsyReqHandle aTsyReqHandle) |
|
413 // |
|
414 // Cancel outstanding modem detection notification, by TSY handle |
|
415 // |
|
416 { |
|
417 LOGTEXT(_L8("Phone:\tDetection Change Notification cancelled")); |
|
418 iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle); |
|
419 return KErrNone; |
|
420 } |
|
421 |
|
422 TInt CPhoneHayes::GetInfo(const TTsyReqHandle aTsyReqHandle, RPhone::TPhoneInfo* aPhoneInfo) |
|
423 { |
|
424 aPhoneInfo->iDetection = iPhoneGlobals->iPhoneStatus.iModemDetected; |
|
425 ReqCompleted(aTsyReqHandle,KErrNone); |
|
426 return KErrNone; |
|
427 } |
|
428 |
|
429 TInt CPhoneHayes::GetCaps(const TTsyReqHandle aTsyReqHandle, RPhone::TCaps* aCaps) |
|
430 // |
|
431 // Get the phone capabilities |
|
432 // |
|
433 { |
|
434 LOGTEXT(_L8("Phone:\tExecuting Get Caps")); |
|
435 aCaps->iFlags = iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags; |
|
436 ReqCompleted(aTsyReqHandle,KErrNone); |
|
437 return KErrNone; |
|
438 } |
|
439 |
|
440 TInt CPhoneHayes::GetStatus(const TTsyReqHandle aTsyReqHandle,RPhone::TStatus* aStatus) |
|
441 // |
|
442 // Get the phone status |
|
443 // |
|
444 { |
|
445 LOGTEXT(_L8("Phone:\tExecuting Get Status")); |
|
446 aStatus->iMode = iPhoneGlobals->iPhoneStatus.iMode; |
|
447 aStatus->iModemDetected = iPhoneGlobals->iPhoneStatus.iModemDetected; |
|
448 ReqCompleted(aTsyReqHandle,KErrNone); |
|
449 return KErrNone; |
|
450 } |
|
451 |
|
452 TInt CPhoneHayes::EnumerateLines(const TTsyReqHandle aTsyReqHandle, TInt* aParams) |
|
453 // |
|
454 // Enumerate the lines |
|
455 // |
|
456 { |
|
457 LOGTEXT(_L8("Phone:\tSubmitting Enumerate Lines")); |
|
458 *aParams = KNumberOfLines; |
|
459 ReqCompleted(aTsyReqHandle,KErrNone); |
|
460 return KErrNone; |
|
461 } |
|
462 |
|
463 TInt CPhoneHayes::GetLineInfo(const TTsyReqHandle aTsyReqHandle, TLineInfoIndex* aParams) |
|
464 // |
|
465 // TLineInfoIndex specifies which of the two lines' info is requested. If that line has not |
|
466 // been created yet, default info is passed back. |
|
467 // |
|
468 { |
|
469 LOGTEXT(_L8("Phone:\tGet Line Info")); |
|
470 if (aParams->iIndex==KFaxLineIndex) |
|
471 { |
|
472 if (iFaxLine!=NULL) |
|
473 { |
|
474 aParams->iInfo.iStatus = iPhoneGlobals->iPhoneStatus.iLineStatus; |
|
475 aParams->iInfo.iName = iFaxLine->iLineName; |
|
476 aParams->iInfo.iLineCapsFlags = (RLine::KCapsFax|RLine::KCapsEventIncomingCall); |
|
477 } |
|
478 else |
|
479 { |
|
480 aParams->iInfo = iDefaultFaxLineInfo; |
|
481 } |
|
482 ReqCompleted(aTsyReqHandle,KErrNone); |
|
483 } |
|
484 else if (aParams->iIndex==KDataLineIndex) |
|
485 { |
|
486 if (iDataLine!=NULL) |
|
487 { |
|
488 aParams->iInfo.iStatus = iPhoneGlobals->iPhoneStatus.iLineStatus; |
|
489 aParams->iInfo.iName = iDataLine->iLineName; |
|
490 aParams->iInfo.iLineCapsFlags = (RLine::KCapsData|RLine::KCapsEventIncomingCall); |
|
491 } |
|
492 else |
|
493 { |
|
494 aParams->iInfo = iDefaultDataLineInfo; |
|
495 } |
|
496 ReqCompleted(aTsyReqHandle,KErrNone); |
|
497 } |
|
498 else if (aParams->iIndex==KVoiceLineIndex) |
|
499 { |
|
500 if (iVoiceLine!=NULL) |
|
501 { |
|
502 aParams->iInfo.iStatus = iPhoneGlobals->iPhoneStatus.iLineStatus; |
|
503 aParams->iInfo.iName = iVoiceLine->iLineName; |
|
504 aParams->iInfo.iLineCapsFlags = (RLine::KCapsVoice|RLine::KCapsEventIncomingCall); |
|
505 } |
|
506 else |
|
507 { |
|
508 aParams->iInfo = iDefaultVoiceLineInfo; |
|
509 } |
|
510 ReqCompleted(aTsyReqHandle,KErrNone); |
|
511 } |
|
512 else |
|
513 { |
|
514 ReqCompleted(aTsyReqHandle,KErrNotFound); |
|
515 } |
|
516 return KErrNone; |
|
517 } |
|
518 |
|
519 void CPhoneHayes::RemoveLine(CLineHayes* aLineHayes) |
|
520 // |
|
521 // When a line closes, it calls this to remove its pointer from CPhoneHayes |
|
522 // |
|
523 { |
|
524 if (aLineHayes == iDataLine) |
|
525 iDataLine=NULL; |
|
526 if (aLineHayes == iFaxLine) |
|
527 iFaxLine=NULL; |
|
528 if (aLineHayes == iVoiceLine) |
|
529 iVoiceLine=NULL; |
|
530 } |
|
531 |
|
532 void CPhoneHayes::StartWaitForRing() |
|
533 { |
|
534 iWaitForCall->StartWait(); |
|
535 } |
|
536 |
|
537 void CPhoneHayes::SetCallRinging(TInt aIndex) |
|
538 // |
|
539 // If a call has had AnswerIncomingCall() called on it, this will be used to answer immediately. |
|
540 // If a NotifyIncomingCall has been called on a line, use PreAlloc call on it and complete notify. |
|
541 // |
|
542 // Returns ETrue if a call has begun to answer, otherwise EFalse |
|
543 { |
|
544 _LIT16(KNokiaMatchString,"*Nokia*"); |
|
545 TBool nokiaPhone=(iPhoneGlobals->iPhoneId.iManufacturer.MatchF(KNokiaMatchString)==0); |
|
546 |
|
547 // If its not a Nokia Phone or its an incoming voice or fax call (i.e. anything other than data) |
|
548 // then do the proper thing... |
|
549 if((!nokiaPhone)||(aIndex==KVoiceLineIndex)||(aIndex==KFaxLineIndex)) |
|
550 { |
|
551 CLineHayes* line=NULL; |
|
552 switch (aIndex) |
|
553 { |
|
554 case KFaxLineIndex: |
|
555 line=iFaxLine; |
|
556 break; |
|
557 case KDataLineIndex: |
|
558 line=iDataLine; |
|
559 break; |
|
560 case KVoiceLineIndex: |
|
561 line=iVoiceLine; |
|
562 break; |
|
563 default: |
|
564 return; |
|
565 }; |
|
566 |
|
567 if (line==NULL) |
|
568 { |
|
569 LOGTEXT(_L8("No line has been opened")); |
|
570 return; |
|
571 } |
|
572 LOGTEXT(_L8("Calling AnswerIfPossible on line")); |
|
573 if (line->AnswerIfPossible()) |
|
574 return; |
|
575 LOGTEXT(_L8("Calling SetPreAllocCall on line")); |
|
576 line->SetPreAllocCall(); |
|
577 return; |
|
578 } |
|
579 else |
|
580 { |
|
581 // Otherwise we need to handle the Nokia's ambiguous data call signal: it could actually be |
|
582 // data or fax |
|
583 LOGTEXT(_L8("SetCallRinging()\tDetected an incoming data call on a Nokia phone")); |
|
584 SetAmbiguousDataFaxCallRinging(); |
|
585 return; |
|
586 } |
|
587 } |
|
588 |
|
589 void CPhoneHayes::SetAmbiguousDataFaxCallRinging() |
|
590 // |
|
591 // Answer or set a call or line as ringing when the string from the modem could either |
|
592 // indicate it is a data call or a fax call. The algorithm below has to make a decision |
|
593 // based on ETel clients behaviour as to whether the incoming call should be treated as |
|
594 // data or fax. |
|
595 // |
|
596 { |
|
597 if((iDataLine)&&(iDataLine->AnswerIfPossible())) // First priority: if we're waiting for a Data call, answer it |
|
598 { |
|
599 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tInterpretting as data call")); |
|
600 return; |
|
601 } |
|
602 if((iFaxLine)&&(iFaxLine->AnswerIfPossible())) // Second priority: if we're waiting for a Fax call, answer it |
|
603 { |
|
604 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tInterpretting as fax call")); |
|
605 return; |
|
606 } |
|
607 // If there are no "answer an incoming call" requests, then see if we can determine it from the lines that are open... |
|
608 if(!iFaxLine && iDataLine) |
|
609 { |
|
610 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tLine object creation: SetPreAllocCall on DataLine")); |
|
611 iDataLine->SetPreAllocCall(); |
|
612 return; |
|
613 } |
|
614 if(!iDataLine && iFaxLine) |
|
615 { |
|
616 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tLine object creation: SetPreAllocCall on FaxLine")); |
|
617 iFaxLine->SetPreAllocCall(); |
|
618 return; |
|
619 } |
|
620 // So both lines MIGHT exist. It's then down to Notify on incoming call notifications, |
|
621 // and we'll make a priority call in favour of data... |
|
622 // First ensure that either a Data line or a Fax line does exist (Nokia 7110 fix: returns |
|
623 // +CRING: REL ASYNC for a voice call (hence a voice line is created). This response |
|
624 // however, is correctly treated as an incoming indication for a Data or Fax call). |
|
625 if (iDataLine) |
|
626 { |
|
627 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tA DataLine has been found. Now checking for an outstanding Notification")); |
|
628 |
|
629 if((iDataLine->IsNotifyIncomingCallOutstanding())&& |
|
630 (!iFaxLine->IsNotifyIncomingCallOutstanding())) |
|
631 { |
|
632 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tNotify: SetPreAllocCall on DataLine")); |
|
633 iDataLine->SetPreAllocCall(); |
|
634 } |
|
635 } |
|
636 else |
|
637 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tNo DataLine has been found; this may be a voice call")); |
|
638 if (iFaxLine) |
|
639 { |
|
640 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tA FaxLine has been found. Now checking for an outstanding Notification")); |
|
641 if ((iFaxLine->IsNotifyIncomingCallOutstanding()) && |
|
642 (!iDataLine->IsNotifyIncomingCallOutstanding())) |
|
643 { |
|
644 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tNotify: SetPreAllocCall on FaxLine")); |
|
645 iFaxLine->SetPreAllocCall(); |
|
646 } |
|
647 } |
|
648 else |
|
649 LOGTEXT(_L8("SetAmbiguousDataFaxCallRinging()\tNo FaxLine has been found; this may be a voice call")); |
|
650 } |
|
651 |
|
652 void CPhoneHayes::StopRinging() |
|
653 { |
|
654 if (iDataLine) |
|
655 { |
|
656 (void)iDataLine->StopMyCallRinging(); |
|
657 iDataLine->ResetPreAllocCall(); // this may not revert the call to PreAlloc status as |
|
658 // the call may have been opened by a client but not |
|
659 // answered. |
|
660 } |
|
661 if (iFaxLine) |
|
662 { |
|
663 (void)iFaxLine->StopMyCallRinging(); |
|
664 iFaxLine->ResetPreAllocCall(); // ditto |
|
665 } |
|
666 if (iVoiceLine) |
|
667 { |
|
668 (void)iVoiceLine->StopMyCallRinging(); |
|
669 iVoiceLine->ResetPreAllocCall(); // ditto |
|
670 } |
|
671 } |
|
672 |
|
673 void CPhoneHayes::StopRingCounter() const |
|
674 { |
|
675 iPhoneGlobals->iNotificationStore->RemoveEventFromLastEvents(ERingOccurred); |
|
676 iWaitForCall->ResetRingCounter(); |
|
677 } |
|
678 |
|
679 void CPhoneHayes::SetHookStatus(RCall::THookStatus aHookStatus) |
|
680 { |
|
681 if (iDataLine) |
|
682 iDataLine->SetCallsHookStatus(aHookStatus); |
|
683 if (iFaxLine) |
|
684 iFaxLine->SetCallsHookStatus(aHookStatus); |
|
685 } |
|
686 |
|
687 TBool CPhoneHayes::CheckForOutstandingAnswer() const |
|
688 // |
|
689 // Returns TRUE if any call in the system has AnswerIncomingCall() outstanding on it. |
|
690 // |
|
691 { |
|
692 TBool check=EFalse; |
|
693 if (iDataLine) |
|
694 check = iDataLine->CheckForOutstandingAnswer(); |
|
695 if (!check && iFaxLine) |
|
696 check = iFaxLine->CheckForOutstandingAnswer(); |
|
697 if (!check && iVoiceLine) |
|
698 check = iVoiceLine->CheckForOutstandingAnswer(); |
|
699 return check; |
|
700 } |
|
701 |
|
702 void CPhoneHayes::CancelOtherRingingCall(CLineHayes* aLine) const |
|
703 { |
|
704 if (iFaxLine && aLine!=iFaxLine) |
|
705 { |
|
706 (void)iFaxLine->StopMyCallRinging(); |
|
707 iFaxLine->ResetPreAllocCall(); |
|
708 } |
|
709 |
|
710 if (iDataLine && aLine!=iDataLine) |
|
711 { |
|
712 (void)iDataLine->StopMyCallRinging(); |
|
713 iDataLine->ResetPreAllocCall(); |
|
714 } |
|
715 if (iVoiceLine && aLine!=iVoiceLine) |
|
716 { |
|
717 (void)iVoiceLine->StopMyCallRinging(); |
|
718 iVoiceLine->ResetPreAllocCall(); |
|
719 } |
|
720 } |
|
721 |
|
722 const CArrayFixFlat<TInt>* CPhoneHayes::ArrayOfMemberDataSizes(const TInt /*aIpc*/) const |
|
723 { |
|
724 return iSizeOfMemberData; |
|
725 } |