fax/faxclientandserver/FAXSVR/CFAX20.CPP
changeset 20 244d7c5f118e
parent 19 1f776524b15c
child 23 6b1d113cdff3
equal deleted inserted replaced
19:1f776524b15c 20:244d7c5f118e
     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 "FAXSERV.H"
       
    17 #include "fax_reversebytes.h"
       
    18 #include "FAXMODEM.H"
       
    19 #include "FAXMDRV.H"
       
    20 
       
    21 #include "FAXLOG.H"
       
    22 
       
    23 const TInt KClass20HangupStatusTimer=20;	// < Time used to wait for final +FHS: report.  Was 5s, but typical GSM delays range between 4s and 10s.
       
    24 
       
    25 // this module has two parts
       
    26 // first receive routines rx
       
    27 // second transmit routines tx
       
    28 
       
    29 /********************************************************************/
       
    30 
       
    31 CFaxModemDriver* CFaxClass20::NewLC(TFaxServerSessionSettings * aFaxServerSessionSettings, RFax::TProgress & aProgress)
       
    32 	{
       
    33 	CFaxModemDriver* self = new(ELeave) CFaxClass20;
       
    34 	CleanupStack::PushL(self);
       
    35 	self->ConstructL(aFaxServerSessionSettings, aProgress);
       
    36 	return self;
       
    37 	}
       
    38 
       
    39 CFaxModemDriver* CFaxClass20::NewL(TFaxServerSessionSettings * aFaxServerSessionSettings, RFax::TProgress & aProgress)
       
    40 	{
       
    41 	CFaxModemDriver* self = NewLC(aFaxServerSessionSettings, aProgress);
       
    42 	CleanupStack::Pop();
       
    43 	return self;
       
    44 	}
       
    45 /********************************************************************/
       
    46 
       
    47 TInt CFaxClass20::RxConnectL()
       
    48 	{
       
    49 	__FLOG_FAXSRV( _L8("CFaxClass20::RxConnectL entering"));
       
    50 
       
    51 	CheckCadenceExportL (_L8 ("AT+FNR=1,1,1,0\r"));
       
    52 	if ((iModem->GetMatchL (_L8 ("OK"), 5)) == 0)
       
    53 		return (KFaxErrModemNotWorking);
       
    54 
       
    55 	CheckCadenceExportL(_L8("AT+FCC=?\r"));
       
    56 	if (!(iModem->ImportL (iResults, 35)))
       
    57 		return (KFaxErrModemNotWorking);
       
    58 
       
    59 	iModem->iOurMessage.Format (_L8 ("%S"), &iResults);
       
    60 	iModem->ProgressUpdateL ();
       
    61 	ParseResults (iResults);
       
    62 
       
    63 	iModem->GetMatchL (_L8 ("OK"), 2);
       
    64 
       
    65 	if (iFaxServerSessionSettings->iRxResolution == EFaxNormal)
       
    66 		iModem->iProgress.iResolution = EFaxNormal;
       
    67 	else
       
    68 		iModem->iProgress.iResolution = EFaxFine;
       
    69 
       
    70 	if (iFaxServerSessionSettings->iRxCompression == EModifiedRead)
       
    71 		iModem->iProgress.iCompression = EModifiedRead;
       
    72 	else
       
    73 		iModem->iProgress.iCompression = EModifiedHuffman;
       
    74 
       
    75 	iActualFaxSpeed = iModem->iProgress.iSpeed;
       
    76 	if (iActualFaxSpeed > iFaxServerSessionSettings->iMaxSpeed)
       
    77 		iActualFaxSpeed = iFaxServerSessionSettings->iMaxSpeed;
       
    78 
       
    79 	if (iFaxServerSessionSettings->iPreferredECM == 0)
       
    80 		iModem->iProgress.iECM = 0;
       
    81 
       
    82 	iResults.Copy(_L8("AT+FCC=0,0,0,2,0,0,0,0\r"));
       
    83 
       
    84 	iResults[7] = (TUint8) (iResults[7] + iModem->iProgress.iResolution);
       
    85 	iResults[9] = (TUint8) (((iActualFaxSpeed / 2400) - 1) + '0');
       
    86 	iResults[15] = (TUint8) (iResults[15] + iModem->iProgress.iCompression);
       
    87 	iResults[17] = (TUint8) (iModem->iProgress.iECM + '0');
       
    88 	CheckCadenceExportL(iResults);
       
    89 	if ((iModem->GetMatchL(_L8("OK"), 3)) == 0)
       
    90 		{
       
    91 		return (KFaxErrModemNotWorking);
       
    92 		}
       
    93 	CheckCadenceExportL(_L8 ("AT+FAA=0\r"));
       
    94 	if ((iModem->GetMatchL(_L8("OK"), 5)) == 0)
       
    95 		{
       
    96 		return (KFaxErrNoReceiveMode);
       
    97 		}
       
    98 
       
    99 	TBuf8<RCall::KFaxIdUserNameMaxSize> narrowBuf;
       
   100 	narrowBuf.Copy(iFaxServerSessionSettings->iFaxId);	 // convert from unicode to narrow
       
   101 	
       
   102 	//-- By Dmitry Lyokhin. concerns PIA-58ELQK defect.
       
   103 	if( narrowBuf.Length() < 1 )
       
   104 		{
       
   105 		narrowBuf.Append(' ');
       
   106 		}
       
   107 
       
   108 	if (iFaxServerSessionSettings->iMode & KFaxPoll)
       
   109 		{
       
   110 		iModem->ExportL(_L8 ("AT+FSP=1\r"));
       
   111 		if ((iModem->GetMatchL(_L8("OK"), 5)) == 0)
       
   112 			{
       
   113 			return (KFaxPollingUnsupported);
       
   114 			}
       
   115 		iModem->ExportL(_L8("AT+FPI=\""));
       
   116 		iModem->ExportL(narrowBuf);
       
   117 		iModem->ExportL(_L8 ("\"\r"));
       
   118 		if ((iModem->GetMatchL(_L8("OK"), 3)) == 0)
       
   119 			{
       
   120 			return (KFaxPollingUnsupported);
       
   121 			}
       
   122 		}
       
   123 	else
       
   124 		{
       
   125 		CheckCadenceExportL(_L8("AT+FCR=1\r"));
       
   126 		if ((iModem->GetMatchL(_L8("OK"), 5)) == 0)
       
   127 			{
       
   128 			return (KFaxErrNoReceiveMode);
       
   129 			}
       
   130 		CheckCadenceExportL(_L8("AT+FLI=\""));
       
   131 		iModem->ExportL(narrowBuf);
       
   132 		iModem->ExportL(_L8("\"\r"));
       
   133 		if ((iModem->GetMatchL(_L8("OK"), 3)) == 0)
       
   134 			{
       
   135 			return (KFaxErrModemNotWorking);
       
   136 			}
       
   137 		}
       
   138 
       
   139 	if (iFaxServerSessionSettings->iMode & KFaxWaitForRing)
       
   140 		{
       
   141 //		while ((iModem->GetMatchL(_L8("RING"), 3)) == 0);
       
   142 //		iTimeOfLastRing.UniversalTime();
       
   143 		}
       
   144 	else
       
   145 		{
       
   146 		if ((iFaxServerSessionSettings->iMode & KFaxOffHook) == 0)
       
   147 			{
       
   148 			DialFaxOnDemandL();
       
   149 			}
       
   150 		}
       
   151 
       
   152 	if ((iFaxServerSessionSettings->iMode & KFaxPoll) == 0)
       
   153 		{
       
   154 		CheckCadenceExportL(_L8("ATA\r"));
       
   155 		}
       
   156 
       
   157 	iModem->iProgress.iPhase = ECallEstablishment;
       
   158 
       
   159 	TInt pollDocsAvailable = 0;
       
   160 
       
   161 	for (;;)
       
   162 		{
       
   163 		if(!(iModem->ImportL(iResults, 35)))
       
   164 			{
       
   165 			return KFaxErrCannotAnswer;
       
   166 			}
       
   167 
       
   168 		iModem->iOurMessage.Format(_L8("%S"), &iResults);
       
   169 		iModem->ProgressUpdateL();
       
   170 
       
   171 		if ((iResults.FindF(_L8("NO DIALTONE"))) >= 0 ||
       
   172 			iResults.FindF(_L8("NO DIAL TONE")) >= 0)
       
   173 			return (KFaxErrNoDialTone);
       
   174 		if ((iResults.FindF(_L8("BUSY"))) >= 0)
       
   175 			return (KFaxErrBusy);
       
   176 		if ((iResults.FindF(_L8("NO ANSWER"))) >= 0)
       
   177 			return (KFaxErrNoAnswer);
       
   178 		if ((iResults.FindF(_L8("NO CARRIER"))) >= 0)
       
   179 			return (KFaxErrNoCarrier);
       
   180 		if ((iResults.FindF(_L8("OK"))) >= 0)
       
   181 			break;
       
   182 		if ((iResults.FindF(_L8("FHS"))) >= 0)
       
   183 			return (KFaxErrPrematureHangup);
       
   184 		if ((iResults.FindF(_L8("FCO"))) >= 0)
       
   185 			iModem->iProgress.iPhase = ESessionNegotiation;
       
   186 		else if ((iResults.FindF(_L8("FPO"))) >= 0)
       
   187 			pollDocsAvailable = 1;
       
   188 		else if ((iResults.FindF(_L8("FTI"))) >= 0)
       
   189 			ExtractAnswerback(iResults);
       
   190 		else if ((iResults.FindF(_L8("FCS"))) >= 0)
       
   191 			ParseResults(iResults);
       
   192 		}
       
   193 
       
   194 	if ((iFaxServerSessionSettings->iMode & KFaxPoll) && (pollDocsAvailable == 0))
       
   195 		return (KFaxNothingToPoll);
       
   196 
       
   197 	iModem->iOurMessage.Format(_L8 ("about to receive fax"));
       
   198 	iModem->ProgressUpdateL();
       
   199 	return RxPrePageL();
       
   200 	}
       
   201 
       
   202 /********************************************************************/
       
   203 TInt CFaxClass20::RxPrePageL()
       
   204 	{
       
   205 	__FLOG_FAXSRV( _L8("CFaxClass20::RxPrePageL entering"));
       
   206 
       
   207 	iModem->ExportL(_L8 ("AT+FDR\r"));
       
   208 	for (;;)
       
   209 		{
       
   210 		if (!(iModem->ImportL (iResults, 35)))
       
   211 			return (KFaxErrCannotConnect);
       
   212 
       
   213 		iModem->iOurMessage.Format (_L8 ("%S"), &iResults);
       
   214 		iModem->ProgressUpdateL ();
       
   215 
       
   216 		if ((iResults.FindF (_L8 ("ERROR"))) >= 0)
       
   217 			return (KFaxErrNoReceiveMode);
       
   218 		if ((iResults.FindF (_L8 ("FHS"))) >= 0)
       
   219 			return (KFaxErrPrematureHangup);
       
   220 		if ((iResults.FindF (_L8 ("CONNECT"))) >= 0)
       
   221 			break;
       
   222 		if ((iResults.FindF (_L8 ("FCS"))) >= 0)
       
   223 			ParseResults (iResults);
       
   224 		}
       
   225 
       
   226 	iModem->TxcharL (Kdc2);
       
   227 	return (RxStartPageL ());
       
   228 }
       
   229 /********************************************************************/
       
   230 TInt CFaxClass20::RxPostPageL ()
       
   231 {
       
   232     __FLOG_FAXSRV( _L8("CFaxClass20::RxPostPageL entering"));
       
   233 
       
   234 	iModem->iProgress.iPhase = EPostPageStatus;
       
   235 	iModem->ProgressUpdateL ();
       
   236 	for (;;)
       
   237 		{
       
   238 		if (iModem->iProgress.iECM == 0)
       
   239 			{
       
   240 			if (!(iModem->ImportL (iResults, 20)))
       
   241 				return (KFaxErrModemResponse);
       
   242 			}
       
   243         else
       
   244             {
       
   245             // coverity[check_return]
       
   246             iModem->ImportL (iResults, 0x7fff);     // no timeout if ECM enabled
       
   247             }
       
   248 
       
   249 		iModem->iOurMessage.Format (_L8 ("%S"), &iResults);
       
   250 		iModem->ProgressUpdateL ();
       
   251 
       
   252 		if ((iResults.FindF (_L8 ("OK"))) >= 0)
       
   253 			return (KFaxErrPrematureOK);
       
   254 		if ((iResults.FindF (_L8 ("FHS"))) >= 0)
       
   255 			return (KFaxErrPrematureHangup);
       
   256 		if ((iResults.FindF (_L8 ("FET"))) >= 0)
       
   257 			break;
       
   258 		}
       
   259 	if (iModem->GetMatchL (_L8 ("OK"), 5) == 0)
       
   260 		return (KFaxErrNoFinalOK);
       
   261 
       
   262 	if ((iResults.FindF (_L8 ("0"))) >= 0)
       
   263 		{
       
   264 		iModem->iOurMessage.Format (_L8 ("page %u successfully received"), iModem->iProgress.iPage);
       
   265 		iModem->ProgressUpdateL ();
       
   266 		return (RxPrePageL ());
       
   267 		}
       
   268 	if ((iResults.FindF (_L8 ("1"))) >= 0)
       
   269 		{
       
   270 		iModem->iOurMessage.Format (_L8 ("page %u successfully received : end of document"), iModem->iProgress.iPage);
       
   271 		iModem->ProgressUpdateL ();
       
   272 		iModem->iOurMessage.Format (_L8 ("Next fax awaited"));
       
   273 		iModem->ProgressUpdateL ();
       
   274 		return (RxPrePageL ());
       
   275 		}
       
   276 	if ((iResults.FindF (_L8 ("2"))) >= 0)
       
   277 		{
       
   278 		iModem->iOurMessage.Format (_L8 ("Final page %u successfully received"), iModem->iProgress.iPage);
       
   279 		iModem->ProgressUpdateL ();
       
   280 		iModem->iProgress.iPhase = EDisconnection;
       
   281 		iModem->ExportL (_L8 ("AT+FDR\r"));
       
   282 		if (iModem->GetMatchL (_L8 ("FHS"), KClass20HangupStatusTimer) == 0)
       
   283 			return (KFaxErrNoHangup);
       
   284 		if (iModem->GetMatchL (_L8 ("OK"), 5) == 0)
       
   285 			return (KFaxErrNoFinalOK);
       
   286 		return (KErrNone);
       
   287 		}
       
   288 	return (KFaxErrUnknownPageCode);
       
   289 }
       
   290 /********************************************************************/
       
   291 
       
   292 TInt CFaxClass20::TxConnectL ()
       
   293 {
       
   294     __FLOG_FAXSRV( _L8("CFaxClass20::TxConnectL entering"));
       
   295 
       
   296 	iModem->ExportL (_L8 ("AT+FNR=1,1,1,0\r"));
       
   297 	if ((iModem->GetMatchL (_L8 ("OK"), 5)) == 0)
       
   298 		return (KFaxErrModemNotWorking);
       
   299 	TBuf8<RCall::KFaxIdUserNameMaxSize> narrowBuf;
       
   300 	narrowBuf.Copy(iFaxServerSessionSettings->iFaxId);	 // convert from unicode to narrow
       
   301 	
       
   302 	//-- By Dmitry Lyokhin. concerns PIA-58ELQK defect.
       
   303 	if( narrowBuf.Length() < 1 ) narrowBuf.Append(' ');
       
   304 
       
   305 	
       
   306 	iModem->ExportL (_L8 ("AT+FLI=\""));
       
   307 	iModem->ExportL (narrowBuf);
       
   308 	iModem->ExportL (_L8 ("\"\r"));
       
   309 	if ((iModem->GetMatchL (_L8 ("OK"), 3)) == 0)
       
   310 		return (KFaxErrModemNotWorking);
       
   311 
       
   312 	iModem->ExportL (_L8 ("AT+FCC=?\r"));
       
   313 	if (!(iModem->ImportL (iResults, 35)))
       
   314 		return (KFaxErrModemNotWorking);
       
   315 
       
   316 	iModem->iOurMessage.Format (_L8 ("%S"), &iResults);
       
   317 	iModem->ProgressUpdateL ();
       
   318 	ParseResults (iResults);
       
   319 
       
   320 	iModem->GetMatchL (_L8 ("OK"), 2);
       
   321 
       
   322 	iActualFaxSpeed = iModem->iProgress.iSpeed;
       
   323 	if (iActualFaxSpeed > iFaxServerSessionSettings->iMaxSpeed)
       
   324 		iActualFaxSpeed = iFaxServerSessionSettings->iMaxSpeed;
       
   325 
       
   326 	if (iFaxServerSessionSettings->iPreferredECM == 0)
       
   327 		iModem->iProgress.iECM = 0;
       
   328 
       
   329 	iResults.Copy (_L8 ("AT+FCC=0,0,0,2,0,0,0,0\r"));
       
   330 
       
   331 	iResults[7] = (TUint8) (iResults[7] + iFaxServerSessionSettings->iTxResolution);
       
   332 	iResults[9] = (TUint8) (((iActualFaxSpeed / 2400) - 1) + '0');
       
   333 
       
   334 	
       
   335 	// added to support 2Dfaxing using class 2.0
       
   336 	if (iModem->iProgress.iCompression)
       
   337 		iResults[15] = (TUint8) (iResults[15] + iFaxServerSessionSettings->iTxCompression);
       
   338 	else
       
   339 		iResults[15] = (TUint8) (iResults[15] + EModifiedHuffman);
       
   340 	
       
   341 	//iResults[15] = (TUint8) (iResults[15] + iFaxServerSessionSettings->iTxCompression);
       
   342 	
       
   343 		
       
   344 	iResults[17] = (TUint8) (iModem->iProgress.iECM + '0');
       
   345 	iModem->ExportL (iResults);
       
   346 	if ((iModem->GetMatchL (_L8 ("OK"), 3)) == 0)
       
   347 		return (KFaxErrModemNotWorking);
       
   348 
       
   349 	iModem->ExportL (_L8 ("ATD"));
       
   350 	if ((iFaxServerSessionSettings->iMode & KFaxOffHook) == 0)
       
   351 		iModem->ExportL (iFaxServerSessionSettings->iPhoneNumber);
       
   352 	iModem->TxcharL (Kreturn);
       
   353 
       
   354 	iModem->iProgress.iPhase = ECallEstablishment;
       
   355 	for (;;)
       
   356 		{
       
   357 		if (!(iModem->ImportL (iResults, KDialTimeout)))
       
   358 			return (KFaxErrNoDial);
       
   359 
       
   360 		iModem->iOurMessage.Format (_L8 ("%S"), &iResults);
       
   361 		iModem->ProgressUpdateL ();
       
   362 
       
   363 		if ((iResults.FindF (_L8 ("NO DIALTONE"))) >= 0 ||
       
   364 			iResults.FindF (_L8 ("NO DIAL TONE")) >= 0)
       
   365 			return (KFaxErrNoDialTone);
       
   366 		if ((iResults.FindF (_L8 ("BUSY"))) >= 0)
       
   367 			return (KFaxErrBusy);
       
   368 		if ((iResults.FindF (_L8 ("NO ANSWER"))) >= 0)
       
   369 			return (KFaxErrNoAnswer);
       
   370 		if ((iResults.FindF (_L8 ("NO CARRIER"))) >= 0)
       
   371 			return (KFaxErrNoCarrier);
       
   372 		if ((iResults.FindF (_L8 ("FHS"))) >= 0)
       
   373 			return (KFaxErrNoNegotiate);
       
   374 		if ((iResults.FindF (_L8 ("OK"))) >= 0)
       
   375 			break;
       
   376 		if ((iResults.FindF (_L8 ("FCO"))) >= 0)
       
   377 			iModem->iProgress.iPhase = ESessionNegotiation;
       
   378 		else if ((iResults.FindF (_L8 ("FCI"))) >= 0)
       
   379 			ExtractAnswerback (iResults);
       
   380 		}
       
   381 	return (TxPrePageL ());
       
   382 }
       
   383 /********************************************************************/
       
   384 TInt CFaxClass20::TxPrePageL ()
       
   385 {
       
   386     __FLOG_FAXSRV(_L8("CFaxClass20::TxPrePageL entering"));
       
   387 
       
   388 	iModem->ExportL (_L8 ("AT+FDT\r"));
       
   389 	for (;;)
       
   390 		{
       
   391 		if (!(iModem->ImportL (iResults, 30)))
       
   392 			return (KFaxErrNoNegotiate);
       
   393 
       
   394 		iModem->iOurMessage.Format (_L8 ("%S"), &iResults);
       
   395 		iModem->ProgressUpdateL ();
       
   396 
       
   397 		if ((iResults.FindF (_L8 ("FHS"))) >= 0)
       
   398 			return (KFaxErrNoNegotiate);
       
   399 		if ((iResults.FindF (_L8 ("CONNECT"))) >= 0)
       
   400 			break;
       
   401 		if ((iResults.FindF (_L8 ("FCS"))) >= 0)
       
   402 			ParseResults (iResults);
       
   403 		}
       
   404 
       
   405 	for (;;)
       
   406 		{
       
   407 		TInt XonTimeoutSec = CLK_TCK * 3; 
       
   408 		
       
   409 		if ((iModem->RxcharWaitL(XonTimeoutSec)) == 0)
       
   410 			{
       
   411 			break;
       
   412 			}
       
   413 
       
   414 		if (iModem->iReadone[0] == Kxon)
       
   415 			{
       
   416 			break;
       
   417 			}
       
   418 		}
       
   419 	return (TxStartPageL());
       
   420 }
       
   421 /********************************************************************/
       
   422 
       
   423 //
       
   424  // TxPostPageL should return either with
       
   425  //
       
   426  // a) an error code and iPhase set to RFax::EPostPageStatus, in which case the send returns with the error
       
   427  // b) KErrNone and iPhase set to RFax::EDataTransfer, in which case we send the next page
       
   428  // c) KErrNone and iPhase set to RFax::EDisconnection, in which case the send returns with KErrNone
       
   429  //
       
   430 
       
   431 TInt CFaxClass20::TxPostPageL ()
       
   432 {
       
   433 	if (iModem->iProgress.iCompression == EModifiedRead)
       
   434 		{
       
   435 		iModem->iTransmitBuffer.Append (0x00);
       
   436 		iModem->iTransmitBuffer.Append (0x60);
       
   437 		iModem->iTransmitBuffer.Append (0x00);
       
   438 		iModem->iTransmitBuffer.Append (0x0C);
       
   439 		iModem->iTransmitBuffer.Append (0x80);
       
   440 		iModem->iTransmitBuffer.Append (0x01);
       
   441 		iModem->iTransmitBuffer.Append (0x30);
       
   442 		iModem->iTransmitBuffer.Append (0x00);
       
   443 		iModem->iTransmitBuffer.Append (0x06);
       
   444 		iModem->iTransmitBuffer.Append (0xC0);
       
   445 		}
       
   446 	else
       
   447 		{
       
   448 		for (TInt x = 3; x; x--)
       
   449 			{
       
   450 			iModem->iTransmitBuffer.Append (0x0);
       
   451 			iModem->iTransmitBuffer.Append (0x08);
       
   452 			iModem->iTransmitBuffer.Append (0x80);
       
   453 			}
       
   454 		}
       
   455 
       
   456 	iModem->iTransmitBuffer.Append (Kdle);
       
   457 	iModem->iOurMessage.Format (_L8 ("RTC transmitted after %d lines"), iModem->iProgress.iLines);
       
   458 	iModem->ProgressUpdateL ();
       
   459 	if (iFaxServerSessionSettings->iTxPages == iModem->iProgress.iPage)
       
   460 		{
       
   461 		iModem->iTransmitBuffer.Append (0x2e);
       
   462 		iModem->iOurMessage.Format (_L8 ("End of document transmitted <dle><eop>"));
       
   463 		}
       
   464 	else
       
   465 		{
       
   466 		iModem->iTransmitBuffer.Append (0x2c);
       
   467 		iModem->iOurMessage.Format (_L8 ("End of page %u transmitted <dle><mps>"), iModem->iProgress.iPage);
       
   468 		}
       
   469     __FLOG_FAXSRV( iModem->iOurMessage);
       
   470 
       
   471 	iModem->CommitTransmitBufferL ();
       
   472 
       
   473 	iModem->iProgress.iPhase = EPostPageStatus;
       
   474 	iModem->ProgressUpdateL ();
       
   475 	while (iModem->Txstat () != 0)
       
   476 		;
       
   477 	iModem->Xonoff ();
       
   478 
       
   479 	// we've just ended phase C data, so we need to wait for the modem to respond with OK or ERROR
       
   480 
       
   481 	for (;;)
       
   482 		{
       
   483 		if (iModem->iProgress.iECM == 0)
       
   484 			{
       
   485 			if (!(iModem->ImportL (iResults, (32 * 1024) / (iModem->iProgress.iSpeed / 10))))
       
   486 				return (KFaxErrCannotEndData);
       
   487 			}
       
   488         else
       
   489             {
       
   490             // coverity[check_return]
       
   491             iModem->ImportL (iResults, 0x7fff);     // no timeout if ECM enabled, but NO CARRIER possible from some mobile phones
       
   492             if ((iResults.FindF (_L8 ("NO CARRIER"))) >= 0)
       
   493                 return (KFaxErrCannotEndData);
       
   494             }
       
   495 
       
   496 		iModem->iOurMessage.Format (_L8 ("%S"), &iResults);
       
   497 		iModem->ProgressUpdateL ();
       
   498 
       
   499 		if ((iResults.FindF (_L8 ("ERROR"))) >= 0)
       
   500 			break;
       
   501 		if ((iResults.FindF (_L8 ("OK"))) >= 0)
       
   502 			break;
       
   503 		}
       
   504 	if (((iResults.FindF (_L8 ("ERROR"))) >= 0) && (iRepeatPage == 0))
       
   505 		{
       
   506 		iModem->iProgress.iPhase = ESessionNegotiation;
       
   507 		iRepeatPage++;
       
   508 		iModem->iProgress.iPage--;
       
   509 		return (TxPrePageL ());
       
   510 		}
       
   511 	if (iFaxServerSessionSettings->iTxPages != iModem->iProgress.iPage)
       
   512 		{
       
   513 		iRepeatPage = 0;
       
   514 		return (TxPrePageL ());
       
   515 		}
       
   516 	iModem->iProgress.iPhase = EDisconnection;
       
   517 	return (KErrNone);
       
   518 }
       
   519 /********************************************************************/
       
   520