telephonyserverplugins/multimodetsy/hayes/PHONE.CPP
changeset 0 3553901f7fa8
child 19 630d2f34d719
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     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 	}