fax/faxclientandserver/FAXCLI/FAXCLI.CPP
branchRCL_3
changeset 20 07a122eea281
parent 0 3553901f7fa8
equal deleted inserted replaced
19:630d2f34d719 20:07a122eea281
       
     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 "CFAX32.H"
       
    17 #include "dial.h"	                      // we no longer depend on DialStor, so must depend directly on Dial
       
    18 
       
    19 #include "FAXLOG.H"
       
    20 #include "faxsettings.h"
       
    21 
       
    22  #include <commsdattypesv1_1.h>
       
    23  #include <commsdatutils.h>
       
    24  #include <commsdat_partner.h>
       
    25 
       
    26  using namespace CommsDat;
       
    27 
       
    28 TInt FaxClientThread (TAny * session);  // function declaration needed here
       
    29 //TInt FaxConverterThread (TAny *);
       
    30 //RSemaphore jerry;
       
    31 /********************************************************************/
       
    32 
       
    33 
       
    34 /********************************************************************/
       
    35 
       
    36 CFaxTransfer::CFaxTransfer()
       
    37 	: CBase()
       
    38 	{}
       
    39 
       
    40 EXPORT_C CFaxTransfer *CFaxTransfer::NewLC (const TFaxSettings & aFaxSettings)
       
    41 /** Constructs a CFaxTransfer object, which offers the publicly exported 
       
    42 Symbian OS Fax Client API. 
       
    43 As is usual in Symbian OS, the only difference between this function and 
       
    44 NewL() is that this variant pushes the object to the cleanup stack.
       
    45 
       
    46 @param aFaxSettings  A reference to a TFaxSettings object which contains 
       
    47 persistent information applicable to all fax sessions. 
       
    48 @return  Pointer to the newly created object. 
       
    49 @leave KErrNoMemory There is insufficient memory to perform the operation. 
       
    50 @capability None
       
    51 */
       
    52    {
       
    53    CFaxTransfer *self = new (ELeave) CFaxTransfer;
       
    54    CleanupStack::PushL (self);
       
    55    self->ConstructL (aFaxSettings);
       
    56    return self;
       
    57    }
       
    58 
       
    59 EXPORT_C CFaxTransfer *CFaxTransfer::NewL (const TFaxSettings & aFaxSettings)
       
    60 /** Constructs a CFaxTransfer object, which offers the publicly exported 
       
    61 Symbian OS Fax Client API.
       
    62 
       
    63 @param aFaxSettings A reference to a TFaxSettings object, which
       
    64 contains persistent information applicable to all fax sessions. 
       
    65 @return A pointer to the newly created object. 
       
    66 @leave KErrNoMemory There is insufficient memory to perform the operation. 
       
    67 @capability None
       
    68 */
       
    69    {
       
    70    CFaxTransfer *self = NewLC (aFaxSettings);
       
    71    CleanupStack::Pop ();
       
    72    return self;
       
    73    }
       
    74 /********************************************************************/
       
    75 
       
    76 void CFaxTransfer::ConstructL (const TFaxSettings & aFaxSettings)
       
    77    {
       
    78    // we now copy the TFaxSettings passed to us - we then
       
    79    // validate the contents and fill in the DialStor bits.
       
    80    // if we don't know the modem class we find it our here
       
    81    iFaxSettings = aFaxSettings;
       
    82    CFaxSettings *currentsettings;
       
    83    currentsettings = CFaxSettings::NewL ();     // bug fix thanks to MartinA
       
    84    CleanupStack::PushL (currentsettings);       // currentsettings saved
       
    85    currentsettings->ValidateAndSetClassL (&iFaxSettings);       // since this could leave
       
    86    CleanupStack::PopAndDestroy ();      // currentsettings deleted
       
    87 
       
    88 	//   if (((TFaxClass) iFaxSettings.iFaxClass != EClass1) &&
       
    89 	//     ((TFaxClass) iFaxSettings.iFaxClass != EClass2) &&
       
    90 	//       ((TFaxClass) iFaxSettings.iFaxClass != EClass2point0))
       
    91 	//      User::Leave (KFaxCannotAutodetect);
       
    92 
       
    93    iFaxSessionSettings.iFaxClass = (TFaxClass) iFaxSettings.iFaxClass;
       
    94    iFaxSessionSettings.iFaxId.Copy (iFaxSettings.iFaxId);
       
    95    iFaxSessionSettings.iMaxSpeed = iFaxSettings.iMaxSpeed;
       
    96    iFaxSessionSettings.iMinSpeed = iFaxSettings.iMinSpeed;
       
    97    iFaxSessionSettings.iRxResolution = iFaxSettings.iPreferredResolution;
       
    98    iFaxSessionSettings.iRxCompression = iFaxSettings.iPreferredCompression;
       
    99    iFaxSessionSettings.iPreferredECM = iFaxSettings.iPreferredECM;
       
   100    iFaxSessionSettings.iFaxOnDemandDelay = iFaxSettings.iFaxOnDemandDelay;
       
   101 
       
   102    iSource = CFaxTransferSource::NewL ();
       
   103    }
       
   104 /********************************************************************/
       
   105 
       
   106 CFaxTransfer::~CFaxTransfer ()
       
   107 /** Destructor
       
   108 
       
   109 Frees all resources owned by the object, prior to its destruction. */
       
   110    {
       
   111    delete iSource;
       
   112    }
       
   113 /********************************************************************/
       
   114 
       
   115 // this function updates the TFaxTransferProgress structure for the
       
   116 // caller. It should be prior to inspection.
       
   117 
       
   118 EXPORT_C TInt CFaxTransfer::Progress ()
       
   119 /** Causes ETel to update the fax progress information in RFax::TProgress.
       
   120 
       
   121 It should be called prior to displaying the fax progress information.
       
   122 
       
   123 @return KErrNone if successful, otherwise another of the system-wide error 
       
   124 codes. 
       
   125 @capability None
       
   126 */
       
   127 {
       
   128 	if (iFaxStarted)
       
   129 		{
       
   130 		iFaxClientProgress=EProgressRxTx;
       
   131 		return (iFax.GetProgress (iProgress));
       
   132 		}
       
   133 	if (iConverting)
       
   134 		{
       
   135 		iFaxClientProgress=EProgressConverting;
       
   136 		//aProgress=EProgressPreparing;
       
   137 		return (KErrNone);
       
   138 		}
       
   139 
       
   140 	//aProgress=EProgressInitialising;
       
   141 	return (KErrNone);
       
   142 }
       
   143 /********************************************************************/
       
   144 
       
   145 // this function tells faxtrans what phone number to dial
       
   146 // obviously only useful in a dialling mode !
       
   147 // the phone number is translated for the modem and service
       
   148 // and location required using dialstor facilities if they are
       
   149 // available - if not, the number is used in its raw state
       
   150 //
       
   151 // if use of a raw phonenumber is required then the inline function
       
   152 // SetPhoneNumber should be called instead.
       
   153 
       
   154 EXPORT_C void CFaxTransfer::SetPhoneNumberL (TDesC8 & aNumber)
       
   155 /** Resolves a local telephone number into an international number by 
       
   156 taking account of the current location and country.
       
   157 The alternative SetPhoneNumber() should be used if the phone number 
       
   158 must be used in its raw state. One of these functions must be called 
       
   159 before CFaxTransfer::Start() when a fax is to be sent. 
       
   160 This function may leave with KErrNoMemory if there is insufficient 
       
   161 memory to perform the operation. The leave code is one of the system 
       
   162 error codes: see system-wide error codes. 
       
   163 The current location and country information is obtained from the 
       
   164 location table in the communications database.
       
   165 The resolved number is then set as the actual phone number to dial.
       
   166 
       
   167 @param aNumber  Descriptor containing the phone number to be resolved. 
       
   168 @capability WriteUserData
       
   169 */
       
   170 	{
       
   171 	SetPhoneNumber (aNumber);
       
   172 	TBuf < KMaxDialString > rawPhoneNumber;
       
   173 	rawPhoneNumber.Copy (aNumber);
       
   174 
       
   175 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   176 	CMDBSession* db = CMDBSession::NewL(KCDVersion1_2);
       
   177 #else
       
   178 	CMDBSession* db = CMDBSession::NewL(KCDVersion1_1);
       
   179 #endif
       
   180 	CleanupStack::PushL(db);
       
   181 		
       
   182 	// Read the currently selected connection preference and find preferred IAP
       
   183 	TInt prefRank  = 1;
       
   184 	
       
   185 	CCDConnectionPrefsRecord *connectionPrefs =
       
   186 		static_cast<CCDConnectionPrefsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdConnectionPrefsRecord));
       
   187 	CleanupStack::PushL(connectionPrefs);
       
   188 	connectionPrefs->iRanking = prefRank;
       
   189 	connectionPrefs->iDirection = ECommDbConnectionDirectionOutgoing;
       
   190 	TBool error = connectionPrefs->FindL(*db);	
       
   191 	
       
   192 	// The following code is a temporary solution until an issue has been resolved in CommsDat
       
   193 	// start
       
   194 	CCDIAPRecord* tempPIapRecord =
       
   195 		static_cast<CCDIAPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord));
       
   196 	tempPIapRecord->SetRecordId(connectionPrefs->iDefaultIAP);
       
   197 	connectionPrefs->iDefaultIAP.iLinkedRecord = tempPIapRecord;
       
   198 	
       
   199 	CCDIAPRecord* pIapRecord = (CCDIAPRecord*)connectionPrefs->iDefaultIAP.iLinkedRecord;
       
   200 	pIapRecord->SetRecordId(connectionPrefs->iDefaultIAP);
       
   201 	pIapRecord->LoadL(*db);
       
   202 	
       
   203 	CCDBearerRecordBase* tempBearerRecord =
       
   204 		static_cast<CCDBearerRecordBase*>(CCDRecordBase::RecordFactoryL(KCDTIdModemBearerRecord));
       
   205 	tempBearerRecord->SetRecordId(pIapRecord->iBearer);
       
   206 	pIapRecord->iBearer.iLinkedRecord = tempBearerRecord;
       
   207 
       
   208 	CCDBearerRecordBase* pBearerRecord = (CCDBearerRecordBase*) pIapRecord->iBearer.iLinkedRecord;
       
   209 	pBearerRecord->SetRecordId(pIapRecord->iBearer);
       
   210 	pBearerRecord->LoadL(*db);
       
   211 	// end
       
   212 	
       
   213 	TUint32 iapId = pBearerRecord->iRecordTag;
       
   214 	
       
   215 	CCDIAPRecord *iapRecord =
       
   216 		static_cast<CCDIAPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord));
       
   217 	CleanupStack::PushL(iapRecord);
       
   218 	iapRecord->SetRecordId(iapId);
       
   219 	iapRecord->LoadL(*db);
       
   220 
       
   221 	// more temporary code
       
   222 	// start	
       
   223 	CCDBearerRecordBase* tempLocationRecord =
       
   224 		static_cast<CCDBearerRecordBase*>(CCDRecordBase::RecordFactoryL(KCDTIdLocationRecord));
       
   225 	tempLocationRecord->SetRecordId(iapRecord->iLocation);
       
   226 	iapRecord->iLocation.iLinkedRecord = tempLocationRecord;
       
   227 	
       
   228 	CCDLocationRecord* pLocationRecord = (CCDLocationRecord*)iapRecord->iLocation.iLinkedRecord;
       
   229 	pLocationRecord->SetRecordId(iapRecord->iLocation);
       
   230 	pLocationRecord->LoadL(*db);
       
   231 	// end
       
   232 	
       
   233 	//CommsDat Migration: Would this be the correct way to check whether or not a linked record exists:
       
   234 	if (pLocationRecord == NULL)	
       
   235 		{
       
   236 		iPhoneNumber.Copy(rawPhoneNumber);
       
   237 		}
       
   238 	else
       
   239 		{
       
   240 		TBuf<32> serviceType;
       
   241 		serviceType.Copy(iapRecord->iServiceType);
       
   242 
       
   243 		if (!serviceType.Compare(TBuf<32>(DIAL_OUT_ISP)))	// Chargecard only valid for dial out ISP
       
   244 			{
       
   245 			// Get service type id
       
   246 			TUint32 serviceId = iapRecord->iService;
       
   247 			
       
   248 			CCDDialOutISPRecord *ispRecord =
       
   249 				static_cast<CCDDialOutISPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord));
       
   250 			CleanupStack::PushL(ispRecord);
       
   251 			ispRecord->SetRecordId(serviceId);
       
   252 			ispRecord->LoadL(*db);
       
   253 			TUint32 locationId = 0;
       
   254 			TUint32 chargecardId = 0;
       
   255 			TRAPD(err,CommsDatUtils::CCommsDatUtils::ResolvePhoneNumberL(rawPhoneNumber, iPhoneNumber, TParseMode(EForDialing), locationId, chargecardId));
       
   256 			// if resolving the phone number fails, use the raw phone number
       
   257 			if (err)
       
   258 				{
       
   259 				iPhoneNumber.Copy(rawPhoneNumber);
       
   260 				}
       
   261 			
       
   262 			CleanupStack::PopAndDestroy(ispRecord);
       
   263 			}
       
   264 		else
       
   265 			{
       
   266 			iPhoneNumber.Copy(rawPhoneNumber);
       
   267 			}
       
   268 		}
       
   269 	CleanupStack::PopAndDestroy(3); // db, connectionPrefs, iapRecord
       
   270 	}
       
   271 /********************************************************************/
       
   272 
       
   273 // in order to cancel a fax session we set a cancel flag in the lowest
       
   274 // level (CFaxModem) - if this has not yet been fully created then we set
       
   275 // a flag in the next level up (CFaxModemDriver) instead, which is always
       
   276 // going to be there as it is created via CFaxTransfer::ConstructL
       
   277 //
       
   278 // because of the way that the CFaxModem monitors its request flag
       
   279 // we need to avoid multiple cancel requests, so only the first call to
       
   280 // Cancel has any effect on it
       
   281 
       
   282 EXPORT_C void CFaxTransfer::Cancel ()
       
   283 /** Tells the fax engine to cancel the fax session at the first convenient 
       
   284 opportunity.
       
   285 
       
   286 The caller should wait for cancellation to complete, which will usually be 
       
   287 signalled by the fax thread's TRequestStatus completing with a KFaxCancelRequested 
       
   288 error code. After the fax thread completes, Stop() should be called in the 
       
   289 normal way.
       
   290 
       
   291 The function can be called at any time after the call to Start(). 
       
   292 @capability None
       
   293 */
       
   294    {
       
   295    if ((iClientCancel == KRequestPending) || (iClientCancel == KErrNone))
       
   296       {
       
   297       TRequestStatus *cancelClient = &iClientCancel;
       
   298       iDriverThread.RequestComplete (cancelClient, KErrCancel);
       
   299       }
       
   300    }
       
   301 /********************************************************************/
       
   302 
       
   303 EXPORT_C TInt CFaxTransfer::Start (TRequestStatus & aThreadStat)
       
   304 /**
       
   305 Start fax sending or receiving session by launching a separate high priority thread.
       
   306 A call to Start must be paired with a call to Stop as this is an EPOC32 requirement.
       
   307 
       
   308 @param     aThreadStat  thread logon request status
       
   309 @return    thread creation code
       
   310 @capability NetworkServices
       
   311 @capability ReadUserData
       
   312 @capability WriteUserData
       
   313 */
       
   314    {
       
   315     // the heap and stack sizes set here (4K each) are pure guesswork
       
   316     // CFaxModemDriver has allocated heap space in the parent thread
       
   317     // for any objects it needs to create after this stage
       
   318     // stack sizes increased by 512K to allow etel to connect
       
   319 
       
   320    TInt state = KErrNone;
       
   321    TInt heapSize = 0x14000;
       
   322    TInt stackSize = 0x14000;
       
   323 
       
   324 	__FLOG_FAXCLI(_L8(" "));
       
   325 	__FLOG_FAXCLI(_L8("-------------------------- new log --------------------------"));
       
   326 	__FLOG_FAXCLI(_L8("CFaxTransfer::Start, starting FaxClientThread"));
       
   327 	__FLOG_FAXCLI(_L8(" "));
       
   328 
       
   329    state = iDriverThread.Create ((_L ("FaxClientThread")), FaxClientThread, stackSize, heapSize, heapSize, this, EOwnerThread);
       
   330    if (state)
       
   331       {
       
   332       state = KFaxThreadError;
       
   333       }
       
   334    else
       
   335       {
       
   336       aThreadStat = KRequestPending;
       
   337       if (iClientCancel != KErrCancel)
       
   338          iClientCancel = KRequestPending;
       
   339       iDriverThread.Logon (aThreadStat);
       
   340       iDriverThread.SetPriority (EPriorityRealTime);
       
   341       iDriverThread.Resume ();
       
   342       }
       
   343    return (state);
       
   344    }
       
   345 /*********************************************************************/
       
   346 
       
   347 EXPORT_C void CFaxTransfer::Stop ()
       
   348 /** Kills the fax thread once it has completed. 
       
   349 
       
   350 Fax threads do not kill themselves, so every successful call to CFaxTransfer::Start() 
       
   351 must be paired with a call to CFaxTransfer::Stop(). 
       
   352 @capability NetworkServices
       
   353 @capability ReadUserData
       
   354 @capability WriteUserData
       
   355 */
       
   356    {
       
   357    iDriverThread.Close ();
       
   358    }
       
   359 /*********************************************************************/
       
   360 
       
   361 // this is a utility function which is the entry to our thread
       
   362 // it isn't part of any class, but we pass the address
       
   363 // of our CFaxTransfer in so that we can check the
       
   364 // session parameter and get back to the required function
       
   365 //
       
   366 // All possible leaves should be trapped as the return
       
   367 // from this function is the TRequestStatus which the
       
   368 // caller to CFaxTransfer::Start is waiting for.
       
   369 
       
   370 TInt FaxClientThread (TAny * session)
       
   371    {
       
   372 
       
   373 
       
   374    // start of unecessary bureaucracy - error checking left out
       
   375 /*#define CSY_NAME _L("ECUART")
       
   376 #define LDD_NAME _L("ECOMM")
       
   377 #if defined (__WINS__)
       
   378 #define PDD_NAME _L("ECDRV")
       
   379 #else
       
   380 #define PDD_NAME _L("EUART1")
       
   381 #endif*/
       
   382 
       
   383 /*
       
   384    User::LoadPhysicalDevice (PDD_NAME);
       
   385    User::LoadLogicalDevice (LDD_NAME);*/
       
   386 // jerry.CreateGlobal(_L("FaxCliSem"),0,EOwnerProcess);
       
   387    
       
   388    RCommServ server;
       
   389    // coverity[check_return]
       
   390    server.Connect ();
       
   391 // end of unecessary bureaucracy
       
   392 
       
   393    TInt state;
       
   394    CTrapCleanup *cleanup = CTrapCleanup::New ();
       
   395 // CFaxTransfer *faxsession = (CFaxTransfer *) session;
       
   396    CFaxTransfer *faxsession =reinterpret_cast<CFaxTransfer *>(session);
       
   397 	__FLOG_FAXCLI(_L8("FaxClientThread entering..."));
       
   398 
       
   399    state = faxsession->iTelServer.Connect ();
       
   400    if (state == KErrNone)
       
   401    {
       
   402    TBuf<KCommsDbSvrMaxFieldLength> tsyName;
       
   403    TRAP(state,faxsession->GetPhoneModuleNameL(tsyName));
       
   404    if (state==KErrNone)
       
   405 	{
       
   406       state = faxsession->iTelServer.LoadPhoneModule (tsyName);
       
   407       if (state == KErrNone)
       
   408          {
       
   409 		 RTelServer::TPhoneInfo phoneInfo;
       
   410 		 state = faxsession->GetPhoneInfoForTsy(tsyName,phoneInfo);
       
   411 		 if (state == KErrNone)
       
   412 			{
       
   413 			
       
   414 			__FLOG_FAXCLI(_L8("FaxClientThread iPhone.Open"));
       
   415 			state = faxsession->iPhone.Open (faxsession->iTelServer, phoneInfo.iName);
       
   416             if (state == KErrNone)
       
   417 				{
       
   418 				
       
   419 				__FLOG_FAXCLI(_L8("FaxClientThread iLine.Open"));
       
   420 				state = faxsession->iLine.Open (faxsession->iPhone, _L ("Fax"));
       
   421 				if (state == KErrNone)
       
   422 					{
       
   423 					//
       
   424 					// If the call name has been provided, then open the
       
   425 					// existing call, otherwise open a new call.
       
   426 					//
       
   427 					if (faxsession->iCallName.Length() == 0)
       
   428 						{
       
   429 						__FLOG_FAXCLI(_L8("FaxClientThread iCall.OpenNewCall"));
       
   430 						state = faxsession->iCall.OpenNewCall (faxsession->iLine);
       
   431 						}
       
   432 					else
       
   433 						{
       
   434 						__FLOG_FAXCLI(_L8("FaxClientThread iCall.OpenExistingCall"));
       
   435 						state = faxsession->iCall.OpenExistingCall(faxsession->iLine, faxsession->iCallName);
       
   436 						}
       
   437 
       
   438 					if (state == KErrNone)
       
   439 						{
       
   440 						faxsession->iSource->iPage = 0;
       
   441 						if (faxsession->iMode & KFaxReceive)
       
   442 							{
       
   443 							faxsession->iFaxSessionSettings.iMode = RCall::EReceive;
       
   444 							TRAP (state, faxsession->FaxReceiveL ());
       
   445 							
       
   446 							__FLOG_FAXCLI1(_L8("FaxClientThread FaxReceiveL exited state=%d"),state);
       
   447 							
       
   448 							faxsession->iSource->CloseFaxInStore ();
       
   449 							}		
       
   450 			            else
       
   451 					        {
       
   452 							faxsession->iFaxSessionSettings.iMode = RCall::ETransmit;
       
   453 							TRAP (state, faxsession->FaxTransmitL ());
       
   454 							faxsession->iSource->iInstream.Close ();
       
   455 							}
       
   456 
       
   457 	                    // we tidy up by deleting any objects created
       
   458 						// (it does no harm if their pointers are already NULL)
       
   459 						// and we close any streams (which also does no harm
       
   460 						// if they have already been closed)
       
   461 
       
   462 						faxsession->iFaxStarted = EFalse;
       
   463 						faxsession->iFax.Close ();
       
   464 						faxsession->iSource->CloseFaxStore ();
       
   465 						delete faxsession->iSource->iWriteFaxFile;
       
   466 						faxsession->iSource->iWriteFaxFile = NULL;
       
   467 		                delete faxsession->iSource->iReadFaxFile;
       
   468 						faxsession->iSource->iReadFaxFile = NULL;
       
   469 						
       
   470 						faxsession->iSource->iOutstream.Close ();
       
   471 						faxsession->iSource->iInstream.Close ();
       
   472 						
       
   473 						RCall::TStatus callStatus;
       
   474 						faxsession->iCall.GetStatus(callStatus);
       
   475 						
       
   476 						__FLOG_FAXCLI1(_L8("FaxClientThread callStatus=%d"),callStatus);
       
   477 
       
   478 						if (callStatus!=RCall::EStatusIdle)
       
   479 							faxsession->iCall.HangUp ();
       
   480 						
       
   481 						__FLOG_FAXCLI(_L8("FaxClientThread iCall.Close"));
       
   482 						faxsession->iCall.Close ();
       
   483 						}
       
   484 					
       
   485 					__FLOG_FAXCLI(_L8("FaxClientThread iLine.Close"));
       
   486 					faxsession->iLine.Close ();
       
   487 					}
       
   488 				
       
   489 				__FLOG_FAXCLI(_L8("FaxClientThread iPhone.Close"));
       
   490 				faxsession->iPhone.Close ();
       
   491 				}
       
   492 			}
       
   493 		faxsession->iTelServer.UnloadPhoneModule (tsyName);
       
   494 		}
       
   495 		}
       
   496     faxsession->iTelServer.Close ();
       
   497     }
       
   498 
       
   499    delete cleanup;
       
   500 
       
   501 // intercept the etel wrong modem type error
       
   502    if (state == KErrEtelWrongModemType) state = KFaxErrWrongModemType;
       
   503 
       
   504    return (state);
       
   505    }
       
   506 
       
   507 /*********************************************************************/
       
   508 
       
   509 void CFaxTransfer::GetPhoneModuleNameL(TDes& aModuleName) const
       
   510 	{
       
   511 	// AnnW, 9/8/99 - This all assumes that we are taking the modem settings from the 
       
   512 	// dial out IAP, which is fince for now, but may not be in the future?  This may also 
       
   513 	// need modifying for Linda?
       
   514 	
       
   515 	CMDBSession* db = CMDBSession::NewL(KCDVersion1_1);
       
   516 	CleanupStack::PushL(db);
       
   517 	
       
   518 	// Read the currently selected connection preference and find preferred IAP
       
   519 	TInt prefRank  = 1;
       
   520 	
       
   521 	CCDConnectionPrefsRecord *connectionPrefs = 
       
   522 		static_cast<CCDConnectionPrefsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdConnectionPrefsRecord));
       
   523 	CleanupStack::PushL(connectionPrefs);
       
   524 	connectionPrefs->iRanking = prefRank;
       
   525 	connectionPrefs->iDirection = ECommDbConnectionDirectionOutgoing;
       
   526 	connectionPrefs->FindL(*db);
       
   527 	
       
   528 	// The following code is a temporary solution until an issue has been resolved in CommsDat
       
   529 	// start
       
   530 	CCDIAPRecord* tempPIapRecord =
       
   531 		static_cast<CCDIAPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord));
       
   532 	tempPIapRecord->SetRecordId(connectionPrefs->iDefaultIAP);
       
   533 	connectionPrefs->iDefaultIAP.iLinkedRecord = tempPIapRecord;
       
   534 	
       
   535 	CCDIAPRecord* pIapRecord = (CCDIAPRecord*)connectionPrefs->iDefaultIAP.iLinkedRecord;
       
   536 	pIapRecord->SetRecordId(connectionPrefs->iDefaultIAP);
       
   537 	pIapRecord->LoadL(*db);
       
   538 	
       
   539 	CCDBearerRecordBase* tempBearerRecord =
       
   540 		static_cast<CCDBearerRecordBase*>(CCDRecordBase::RecordFactoryL(KCDTIdModemBearerRecord));
       
   541 	tempBearerRecord->SetRecordId(pIapRecord->iBearer);
       
   542 	pIapRecord->iBearer.iLinkedRecord = tempBearerRecord;
       
   543 
       
   544 	CCDBearerRecordBase* pBearerRecord = (CCDBearerRecordBase*) pIapRecord->iBearer.iLinkedRecord;
       
   545 	pBearerRecord->SetRecordId(pIapRecord->iBearer);
       
   546 	pBearerRecord->LoadL(*db);
       
   547 	// end
       
   548 	
       
   549 	TUint32 iapId = pBearerRecord->iRecordTag;
       
   550 	
       
   551 	CMDBField<TUint32>* bearerField = new(ELeave) CMDBField<TUint32>(KCDTIdIAPBearer);
       
   552 	CleanupStack::PushL(bearerField);
       
   553 	bearerField->SetRecordId(iapId);
       
   554 	bearerField->LoadL(*db);
       
   555 	TUint32 modemId = *bearerField;
       
   556 	CleanupStack::PopAndDestroy(bearerField);
       
   557 
       
   558 	CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
       
   559 	CleanupStack::PushL(tsyField);
       
   560 	tsyField->SetRecordId(modemId);
       
   561 	tsyField->SetMaxLengthL(KMaxTextLength);
       
   562 	tsyField->LoadL(*db);
       
   563 	aModuleName = *tsyField;
       
   564 	CleanupStack::PopAndDestroy(tsyField);
       
   565 	
       
   566 	CleanupStack::PopAndDestroy(2); // db, connectionPrefs
       
   567 	}
       
   568 
       
   569 void CFaxTransfer::CancelFaxServerSession ()
       
   570    {
       
   571    if (iMode & KFaxWaitForRing)
       
   572       iCall.AnswerIncomingCallCancel ();
       
   573    else
       
   574       {
       
   575       if (iMode & KFaxOffHook)
       
   576          iCall.ConnectCancel ();
       
   577       else
       
   578          iCall.DialCancel ();
       
   579       }
       
   580    }
       
   581 /*********************************************************************/
       
   582 // receiving a fax is easy because it is passive
       
   583 // just open the file for receiving and off we go
       
   584 
       
   585 void CFaxTransfer::FaxReceiveL ()
       
   586    {
       
   587 
       
   588 	__FLOG_FAXCLI(_L8("CFaxTransfer::FaxReceiveL entering"));
       
   589 
       
   590    if (iMode & KFaxPoll)
       
   591       iFaxSessionSettings.iFaxRetrieveType = RCall::EFaxPoll;
       
   592    else
       
   593       iFaxSessionSettings.iFaxRetrieveType = RCall::EFaxOnDemand;
       
   594 
       
   595    iSource->OpenFaxInL (iReceiveFileName);
       
   596 
       
   597    SetFaxSettingsL();
       
   598 
       
   599    if (iMode & KFaxWaitForRing)
       
   600       {//-- answering incoming call if fax is waiting for a call
       
   601 	  iCall.AnswerIncomingCall (iTransferStatus);	
       
   602       if (iClientCancel != KRequestPending)
       
   603          {//-- cancel request, leave
       
   604          iCall.AnswerIncomingCallCancel ();
       
   605 		 User::WaitForRequest(iTransferStatus);
       
   606          User::Leave (KFaxCancelRequested);
       
   607          }
       
   608       }
       
   609    else	//if (iMode & KFaxWaitForRing) 
       
   610       {//-- if fax is not waiting for a call, dial
       
   611       if (iMode & KFaxOffHook)
       
   612          iCall.Connect (iTransferStatus);
       
   613       else
       
   614          {
       
   615          if (iPhoneNumber.Length() == 0)
       
   616             User::Leave (KErrCouldNotConnect);
       
   617          iCall.Dial (iTransferStatus, iPhoneNumber);
       
   618          }
       
   619       }
       
   620 
       
   621    TRequestStatus reqStatus;
       
   622    RCall::TStatus callStatus;
       
   623    iCall.NotifyStatusChange (reqStatus, callStatus);
       
   624 
       
   625    for (;;)
       
   626       {
       
   627       User::WaitForAnyRequest ();
       
   628       if (reqStatus != KRequestPending)
       
   629          {
       
   630          //-- Call status changed
       
   631          if (reqStatus.Int () != KErrNone)
       
   632             {
       
   633             CancelFaxServerSession ();
       
   634             User::Leave (reqStatus.Int ());
       
   635             }
       
   636          if (iMode & KFaxWaitForRing)
       
   637             {//-- Fax is waiting for a ring
       
   638 			if (callStatus == RCall::EStatusRinging)
       
   639 				{//-- Call status is 'Ringing', continue waiting 
       
   640 				iCall.NotifyStatusChange(reqStatus, callStatus);
       
   641 				reqStatus = KRequestPending;
       
   642 				continue;
       
   643 				}
       
   644 			else 
       
   645 			 //-- due to PIA-586KGE fix (changes in CATAnswerFax::Start()) 'Connecting' may be not noticed here
       
   646 			 //-- so EStatusConnected state is ok
       
   647 			 if (callStatus != RCall::EStatusAnswering && callStatus != RCall::EStatusConnected )
       
   648 					{
       
   649 					iCall.AnswerIncomingCallCancel ();
       
   650 					User::Leave (KFaxEtelServerError);
       
   651 					} //if (callStatus != RCall::EStatusAnswering)
       
   652             } //if (iMode & KFaxWaitForRing)
       
   653          else
       
   654             {//-- Fax is not waiting for a ring 
       
   655             if (iMode & KFaxOffHook)
       
   656                {
       
   657                if (callStatus != RCall::EStatusConnecting)
       
   658                   {
       
   659                   iCall.ConnectCancel ();
       
   660                   User::Leave (KFaxEtelServerError);
       
   661                   }
       
   662                }
       
   663             else if (callStatus != RCall::EStatusDialling)
       
   664                {
       
   665                iCall.DialCancel ();
       
   666                User::Leave (KFaxEtelServerError);
       
   667                }
       
   668             }
       
   669          TInt ret = iFax.Open (iCall);
       
   670          if (ret != KErrNone)
       
   671             {
       
   672             CancelFaxServerSession ();
       
   673             User::Leave (ret);
       
   674             }
       
   675          iFaxStarted = ETrue;
       
   676          reqStatus = KRequestPending;
       
   677          }//if (reqStatus != KRequestPending)
       
   678       else if (iClientCancel != KRequestPending)
       
   679          {//-- Fax cancel request
       
   680          if (iFaxStarted == EFalse)
       
   681             iCall.NotifyStatusChangeCancel ();
       
   682          CancelFaxServerSession ();
       
   683          User::Leave (KFaxCancelRequested);
       
   684          }
       
   685       else if (iTransferStatus != KRequestPending)
       
   686          {//--iCall.AnswerIncomingCall status changed
       
   687          if (iFaxStarted == EFalse)
       
   688             iCall.NotifyStatusChangeCancel ();
       
   689          User::LeaveIfError (iTransferStatus.Int ());
       
   690          break;
       
   691          }
       
   692       else
       
   693          {
       
   694          if (iFaxStarted == EFalse)
       
   695             iCall.NotifyStatusChangeCancel ();
       
   696          CancelFaxServerSession ();
       
   697          User::Leave (KErrCompletion);  // stray event handle
       
   698          }
       
   699       }
       
   700 
       
   701    //-- Data transfer phase
       
   702    User::LeaveIfError (iFax.GetProgress (iProgress));
       
   703    while (iProgress.iPhase == EDataTransfer)
       
   704       {
       
   705       iSource->iResolu = iProgress.iResolution;
       
   706       iSource->iCompression = iProgress.iCompression;
       
   707       for (;;)
       
   708          {
       
   709          iFax.Read (iTransferStatus, iDataBuf);
       
   710          User::WaitForRequest (iTransferStatus, iClientCancel);
       
   711          if (iClientCancel != KRequestPending)
       
   712             {
       
   713             iFax.TerminateFaxSession ();
       
   714             User::Leave (KFaxCancelRequested);
       
   715             }
       
   716          User::LeaveIfError (iTransferStatus.Int ());
       
   717 
       
   718          // the server has buffered up lines to minimize interaction
       
   719          // iDataBuf starts with a TInt containing the number of lines
       
   720          // Each line follows, preceded with a TInt containing its length
       
   721          // which must be copied as it might not be aligned on a 4-byte
       
   722          // boundary - a line of zero length indicates we have reached
       
   723          // the end of the page
       
   724 
       
   725          TUint8 *nextLine = CONST_CAST (TUint8 *, iDataBuf.Ptr ());
       
   726          TInt lengthOfLine=0;
       
   727          TInt numberOfLines;
       
   728 
       
   729          Mem::Copy (&numberOfLines, nextLine, sizeof (TInt));
       
   730          nextLine += sizeof (TInt);
       
   731 
       
   732          while (numberOfLines--)
       
   733             {
       
   734             Mem::Copy (&lengthOfLine, nextLine, sizeof (TInt));
       
   735             if (lengthOfLine == 0)
       
   736                break;
       
   737             nextLine += sizeof (TInt);
       
   738             TPtrC8 currentLine (nextLine, lengthOfLine);
       
   739             iSource->WriteFaxDataL (currentLine);
       
   740             nextLine += lengthOfLine;
       
   741             }
       
   742          if (lengthOfLine == 0)
       
   743             break;
       
   744          }
       
   745       iSource->WritePageParmsL (iProgress.iAnswerback);
       
   746       iFax.WaitForEndOfPage (iTransferStatus);
       
   747       User::WaitForRequest (iTransferStatus, iClientCancel);
       
   748       if (iClientCancel != KRequestPending)
       
   749          {
       
   750          iFax.TerminateFaxSession ();
       
   751          User::Leave (KFaxCancelRequested);
       
   752          }
       
   753       User::LeaveIfError (iTransferStatus.Int ());
       
   754       User::LeaveIfError (iFax.GetProgress (iProgress));
       
   755 	  	  
       
   756       }
       
   757 //	iSource->CloseFaxInStore ();
       
   758     if (iProgress.iCompression==EModifiedRead)
       
   759 		 Convert1dL ();
       
   760    }
       
   761 /*********************************************************************/
       
   762 
       
   763 // sending a fax is rather more complex
       
   764 //
       
   765 // we need a valid phone number (we don't do polling)
       
   766 //
       
   767 // we need a valid list of pages to send
       
   768 //
       
   769 // we need to set the resolution we require to that of the
       
   770 // fax we want to send (use the last page)
       
   771 //
       
   772 
       
   773 void CFaxTransfer::FaxTransmitL ()
       
   774    {
       
   775    
       
   776    
       
   777    __FLOG_FAXCLI(_L8("CFaxTransfer::FaxTransmitL entering"));
       
   778 
       
   779    TBool ConversionStatus=FALSE;
       
   780    //TInt err=0;
       
   781    if (iSource->iOurPreferredCompression==Prefer2D)
       
   782 		{	
       
   783 		TRAPD (retcode,Convert2dL());
       
   784 		if (retcode==KErrNone)
       
   785 			ConversionStatus=TRUE;
       
   786 		else
       
   787 			{
       
   788 			ConversionStatus=FALSE;
       
   789 			iSource->iOurPreferredCompression=Prefer1D;		// if anything goes wrong during conversion
       
   790 			}												// try the 1D version.
       
   791 		}
       
   792    if ((iSource->iFaxPages == 0) || (iSource->iFaxListEntries == 0))
       
   793       User::Leave (KErrNotFound);
       
   794    iSource->iSavedFaxListEntries = iSource->iFaxListEntries;
       
   795    iSource->iOurFaxEntry.iPageCount = 0; 
       
   796    iSource->iInstream.Open (*iSource->iSources);
       
   797    iSource->GetNextPageReadyL ();
       
   798 
       
   799    if (iSource->iOurPreferredCompression==Prefer1D)
       
   800 	   iFaxSessionSettings.iTxPages=iSource->iFaxPages;
       
   801 
       
   802    // we pass in to the server the resolution of the last added source page
       
   803 
       
   804    iFaxSessionSettings.iTxResolution = (TFaxResolution) iSource->iResolu;
       
   805    if ((iSource->iOurPreferredCompression==Prefer2D) && ConversionStatus==TRUE)
       
   806 		iFaxSessionSettings.iTxCompression = (TFaxCompression) EModifiedRead;	
       
   807    else
       
   808 	   iFaxSessionSettings.iTxCompression = (TFaxCompression) iSource->iCompression;
       
   809 
       
   810    SetFaxSettingsL();	// pass the settings to the Fax Server
       
   811    SetSharedFileHandlesL();
       
   812 
       
   813    if (iMode & KFaxOffHook)
       
   814       iCall.Connect (iTransferStatus);
       
   815    else
       
   816       {
       
   817       if (iPhoneNumber.Length() == 0)
       
   818          User::Leave (KErrCouldNotConnect);
       
   819       iCall.Dial (iTransferStatus, iPhoneNumber);
       
   820       }
       
   821 
       
   822    TRequestStatus reqStatus;
       
   823    RCall::TStatus callStatus;
       
   824    iCall.NotifyStatusChange (reqStatus, callStatus);
       
   825 
       
   826    for (;;)
       
   827       {
       
   828       User::WaitForAnyRequest ();
       
   829       if (reqStatus != KRequestPending)
       
   830          {
       
   831          if (reqStatus.Int () != KErrNone)
       
   832 														// initialisation and comm port errors
       
   833             {
       
   834             CancelFaxServerSession ();
       
   835             User::Leave (reqStatus.Int ());
       
   836             }
       
   837          if (iMode & KFaxOffHook)
       
   838             {
       
   839             if (callStatus != RCall::EStatusConnecting)
       
   840                {
       
   841                iCall.ConnectCancel ();
       
   842                User::Leave (KFaxEtelServerError);
       
   843                }
       
   844             }
       
   845          else if (callStatus != RCall::EStatusDialling)
       
   846             {
       
   847             iCall.DialCancel ();
       
   848             User::Leave (KFaxEtelServerError);
       
   849             }
       
   850          TInt ret = iFax.Open (iCall);
       
   851          if (ret != KErrNone)
       
   852             {
       
   853             CancelFaxServerSession ();
       
   854             User::Leave (ret);
       
   855             }
       
   856          iFaxStarted = ETrue;
       
   857          reqStatus = KRequestPending;   // to prevent first scenario being
       
   858 										// chosen each time any request comes in
       
   859          }
       
   860       else if (iClientCancel != KRequestPending)
       
   861          {
       
   862          if (iFaxStarted == EFalse)
       
   863             iCall.NotifyStatusChangeCancel ();
       
   864          CancelFaxServerSession ();
       
   865          User::Leave (KFaxCancelRequested);
       
   866          }
       
   867       else if (iTransferStatus != KRequestPending)
       
   868          {
       
   869          if (iFaxStarted == EFalse)
       
   870             iCall.NotifyStatusChangeCancel ();
       
   871          User::LeaveIfError (iTransferStatus.Int ());
       
   872          break;
       
   873          }
       
   874       else
       
   875          {
       
   876          if (iFaxStarted == EFalse)
       
   877             iCall.NotifyStatusChangeCancel ();
       
   878          CancelFaxServerSession ();
       
   879          User::Leave (KErrCompletion);  // stray event handle
       
   880          }
       
   881       }
       
   882 
       
   883    for (;;)
       
   884       {
       
   885       User::LeaveIfError (iFax.GetProgress (iProgress));
       
   886       TInt thispage = iProgress.iPage;
       
   887       TInt thisline = 1;
       
   888       ASSERT (iSource->iLines);
       
   889 
       
   890 		if ((iProgress.iCompression) && (iSource->iSavedFaxListEntries>=1))
       
   891 			{
       
   892 			while (iSource->iCompression == EModifiedHuffman)		// loop until we 
       
   893 			iSource->GetNextPageReadyL ();							// find the 2D document
       
   894 			}
       
   895 	  
       
   896       //we buffer up lines to minimize client-server interaction
       
   897       //iDataBuf starts with a TInt containing the number of lines
       
   898       //Each line follows, preceded with a TInt containing its length
       
   899       //which must be copied as it might not be aligned on a 4-byte boundary
       
   900 
       
   901       TUint8 *startData;
       
   902       TUint8 *lineData;
       
   903       TInt numberOfLines;
       
   904       const TUint8 *maxData;
       
   905 
       
   906       TUint8 *currentLineData;
       
   907       TInt currentLineLength;
       
   908 
       
   909       for (;;)
       
   910          {
       
   911          lineData = startData = CONST_CAST (TUint8 *, iDataBuf.Ptr ());
       
   912          maxData = startData + iDataBuf.MaxLength () - KMaxT4Des - sizeof (TInt);
       
   913 
       
   914          iDataBuf.SetMax ();
       
   915          numberOfLines = 0;
       
   916          lineData += sizeof (TInt);
       
   917          for (;;)
       
   918             {
       
   919             if (thisline > iSource->iLines)
       
   920                break;
       
   921             thisline++;
       
   922             numberOfLines++;
       
   923             currentLineData = lineData + sizeof (TInt);
       
   924             *currentLineData = 0x0;
       
   925             TPtr8 currentLine (currentLineData + 1, 0, KMaxT4Des - 1);
       
   926             iSource->ReadFaxData (currentLine);
       
   927             currentLineLength = currentLine.Length () + 1;
       
   928             Mem::Copy (lineData, &currentLineLength, sizeof (TInt));
       
   929             lineData += sizeof (TInt);
       
   930             lineData += currentLineLength;
       
   931             if (lineData > maxData)
       
   932                break;
       
   933             }
       
   934          Mem::Copy (startData, &numberOfLines, sizeof (TInt));
       
   935          iDataBuf.SetLength (lineData - startData);
       
   936          iFax.Write (iTransferStatus, iDataBuf);
       
   937          User::WaitForRequest (iTransferStatus, iClientCancel);
       
   938          if (iClientCancel != KRequestPending)
       
   939             {
       
   940             iFax.TerminateFaxSession ();
       
   941             User::Leave (KFaxCancelRequested);
       
   942             }
       
   943          User::LeaveIfError (iTransferStatus.Int ());
       
   944          if (thisline > iSource->iLines)
       
   945             break;
       
   946          }
       
   947       iDataBuf.Zero ();
       
   948       iFax.WaitForEndOfPage (iTransferStatus);
       
   949       User::WaitForRequest (iTransferStatus, iClientCancel);
       
   950       if (iClientCancel != KRequestPending)
       
   951          {
       
   952          iFax.TerminateFaxSession ();
       
   953          User::Leave (KFaxCancelRequested);
       
   954          }
       
   955       User::LeaveIfError (iTransferStatus.Int ());
       
   956       User::LeaveIfError (iFax.GetProgress (iProgress));
       
   957       if (iProgress.iPhase != EDataTransfer)
       
   958          break;
       
   959       if (thispage == iProgress.iPage)
       
   960          iSource->PreviousPageFindL ();
       
   961       else
       
   962          iSource->GetNextPageReadyL ();
       
   963       }
       
   964    if ((iProgress.iCompression==EModifiedHuffman) && (iSource->iOurPreferredCompression==Prefer2D))
       
   965    {
       
   966 	   for (TInt i=0; i<(iSource->iFaxPages/2);i++)
       
   967 	   iSource->GetNextPageReadyL ();						
       
   968    }
       
   969 }
       
   970 
       
   971 void CFaxTransfer::SetFaxSettingsL()
       
   972 	{
       
   973    TInt error;
       
   974    RPhone::TStatus phoneStatus;
       
   975    
       
   976    error=iPhone.GetStatus(phoneStatus);
       
   977 	if (error == KErrNone)
       
   978 		{
       
   979 		if ((phoneStatus.iModemDetected == RPhone::EDetectedNotPresent) || (phoneStatus.iModemDetected == RPhone::EDetectedUnknown))
       
   980 			{
       
   981 			TRequestStatus initialiseStatus;
       
   982 			iPhone.Initialise(initialiseStatus);
       
   983 			User::WaitForAnyRequest();
       
   984 			if (iClientCancel != KRequestPending)
       
   985 				{
       
   986 				iPhone.InitialiseCancel();					// issue initialiseCancel command
       
   987 				User::WaitForRequest(initialiseStatus);		// wait for it to complete
       
   988 				User::Leave(KFaxCancelRequested);			// leave with  KFaxCancelRequested
       
   989 				}	
       
   990 			User::LeaveIfError(initialiseStatus.Int());
       
   991 			}
       
   992 		}   
       
   993    TInt ret=KErrNone;	// so communication with modem has begun...
       
   994    TInt count=0;		// we have a loop where we try three times to set fax settings in the
       
   995 						// unlikely event that the initialisation sequence has just started
       
   996 						// so the phoneStatus gives ModemDetected Present, but the supported fax
       
   997 						// classes have not yet been ascertained.
       
   998    do 
       
   999 	{
       
  1000 	ret=iCall.SetFaxSettings (iFaxSessionSettings);	// retry until init sequence has found out what
       
  1001 													// the fax classes supported are.
       
  1002 	if (ret==KErrEtelUnknownModemCapability)
       
  1003 		User::After(500000);
       
  1004 	}
       
  1005    while (ret==KErrEtelUnknownModemCapability && iClientCancel==KRequestPending && count++<3);
       
  1006    if (iClientCancel!=KRequestPending)
       
  1007 	   ret=KFaxCancelRequested;
       
  1008    User::LeaveIfError(ret);
       
  1009    }
       
  1010 void CFaxTransfer::SetSharedFileHandlesL()
       
  1011 	{
       
  1012 	//Open a file server session and a file handle on the private header file to be shared.
       
  1013 	RFs sharedFs;
       
  1014 	RFile sharedHeaderFile;
       
  1015 	
       
  1016 	User::LeaveIfError(sharedFs.Connect());
       
  1017 	CleanupClosePushL(sharedFs);
       
  1018 	//allow it to be shared
       
  1019 	User::LeaveIfError(sharedFs.ShareProtected());
       
  1020 	
       
  1021 	//get path 
       
  1022 	TFileName headerFullPath;
       
  1023 	CFaxHeaderLines::GeneratePathForHeaderFileL(headerFullPath);
       
  1024 	
       
  1025 	//Open the file in read-only mode
       
  1026 	User::LeaveIfError(sharedHeaderFile.Open(sharedFs, headerFullPath, EFileRead));
       
  1027 	CleanupClosePushL(sharedHeaderFile);
       
  1028 	
       
  1029 	User::LeaveIfError(iCall.AdoptFaxSharedHeaderFile(sharedHeaderFile));
       
  1030 	CleanupStack::PopAndDestroy();//sharedHeaderFile
       
  1031 	CleanupStack::PopAndDestroy();//sharedFs
       
  1032 	}
       
  1033 	
       
  1034 TInt CFaxTransfer::GetPhoneInfoForTsy(const TDes& aTsyName, RTelServer::TPhoneInfo& aPhoneInfo) const
       
  1035 //
       
  1036 //	Finds the index of the phone which belongs to TSY named "aTsyName", and retrieves its info.
       
  1037 //
       
  1038 	{
       
  1039 	 TInt count=0;
       
  1040 	 iTelServer.EnumeratePhones(count);
       
  1041 	 TName matchTsyName;
       
  1042 	 TInt ret = iTelServer.GetTsyName(0,matchTsyName);
       
  1043 	 if (ret == KErrNone)
       
  1044 		{
       
  1045 		 TInt i=0;
       
  1046 		 if (count>1)
       
  1047 			{
       
  1048 			while (matchTsyName.CompareF(aTsyName)!=KErrNone && i++<count && ret==KErrNone)
       
  1049 				ret = iTelServer.GetTsyName(i,matchTsyName);
       
  1050 			}
       
  1051 		 ASSERT(matchTsyName.CompareF(aTsyName)==KErrNone);
       
  1052 		 iTelServer.GetPhoneInfo(i,aPhoneInfo);
       
  1053 		}
       
  1054 	 return ret;
       
  1055 	}
       
  1056 
       
  1057 /********************************************************************/
       
  1058 
       
  1059 EXPORT_C void CFaxTransfer::AddSourceL (const TFileName & aFaxPageStore, TFaxPreferredCompression aPreferredCompression)
       
  1060 /** Specifies which pages of a fax store file should be sent. 
       
  1061 It can be called more than once to add multiple pages from different files. Typically, 
       
  1062 this function is called twice for each transmission: once to queue the cover sheet, 
       
  1063 and a second time to queue the remainder of the fax.
       
  1064 The overloaded variants are supplied primarily to help error recovery in cases when 
       
  1065 a fax transmission is either incomplete or when specific pages need to be resent. 
       
  1066 When transmitting a fax, at least one variant of this function must be called before 
       
  1067 CFaxTransfer::Start().
       
  1068 
       
  1069 @param aFaxPageStore  Name of the fax store file from which to take pages.
       
  1070 @param  aPreferredCompression Preferred compression.
       
  1071 @capability WriteUserData
       
  1072 */
       
  1073    {
       
  1074    iSource->AddSourceL (aFaxPageStore, 1,aPreferredCompression);
       
  1075    }
       
  1076 
       
  1077 EXPORT_C void CFaxTransfer::AddSourceL (const TFileName & aFaxPageStore, TInt aStartPage,TFaxPreferredCompression aPreferredCompression)
       
  1078 /** Specifies which pages of a fax store file should be sent. 
       
  1079 It can be called more than once to add multiple pages from different files. 
       
  1080 Typically, this function is called twice for each transmission: once to queue 
       
  1081 the cover sheet, and a second time to queue the remainder of the fax.
       
  1082 The overloaded variants are supplied primarily to help error recovery in cases 
       
  1083 when a fax transmission is either incomplete or when specific pages need to be 
       
  1084 resent. When transmitting a fax, at least one variant of this function must be 
       
  1085 called before CFaxTransfer::Start().
       
  1086 
       
  1087 @param aFaxPageStore  Name of the fax store file from which to take pages. 
       
  1088 @param aStartPage  Page in file to start from. If omitted, the file is sent 
       
  1089 from the start. 
       
  1090 @param  aPreferredCompression Preferred compression.
       
  1091 @capability WriteUserData
       
  1092 */
       
  1093    {
       
  1094    iSource->AddSourceL (aFaxPageStore, aStartPage, aPreferredCompression);
       
  1095    }
       
  1096 
       
  1097 EXPORT_C void CFaxTransfer::AddSourceL (const TFileName & aFaxPageStore, TInt aStartPage, TInt aEndPage, TFaxPreferredCompression aPreferredCompression)
       
  1098 /**Specifies which pages of a fax store file should be sent. 
       
  1099 It can be called more than once to add multiple pages from different files. 
       
  1100 Typically, this function is called twice for each transmission: once to queue 
       
  1101 the cover sheet, and a second time to queue the remainder of the fax.
       
  1102 The overloaded variants are supplied primarily to help error recovery in cases 
       
  1103 when a fax transmission is either incomplete or when specific pages need to be 
       
  1104 resent. When transmitting a fax, at least one variant of this function must be 
       
  1105 called before CFaxTransfer::Start().
       
  1106 
       
  1107 @param aFaxPageStore  Name of the fax store file from which to take pages. 
       
  1108 @param aStartPage  Page in file to start from. If omitted, the file is sent from the start. 
       
  1109 @param aEndPage  Page in file to stop sending. If omitted, transmission continues to the end. 
       
  1110 @param  aPreferredCompression Preferred compression.
       
  1111 @capability WriteUserData
       
  1112 */
       
  1113    {
       
  1114    iSource->AddSourceL (aFaxPageStore, aStartPage, aEndPage, aPreferredCompression);
       
  1115    }
       
  1116 
       
  1117 //EXPORT_C void CFaxTransfer::AddSourceL (const TFileName & aFaxPageStore, const TFileName & aFaxPageStore2)
       
  1118 //	{
       
  1119 //	iSource->AddSourceL(aFaxPageStore, aFaxPageStore2);
       
  1120 //	}
       
  1121 
       
  1122 EXPORT_C void CFaxTransfer::RemoveAllSources ()
       
  1123 /** Clears the complete list of pages previously selected for faxing using one 
       
  1124 of the variants of AddSourceL(). 
       
  1125 
       
  1126 Removal of individual items from the list of pages to be fax is not possible. 
       
  1127 
       
  1128 This function must be used between successive fax transmissions if previously 
       
  1129 sent pages aren't to be sent again. 
       
  1130 @capability WriteUserData
       
  1131 */
       
  1132    {
       
  1133    iSource->RemoveAllSources ();
       
  1134    }
       
  1135 
       
  1136 /********************************************************************/
       
  1137 void CFaxTransfer::Convert2dL ()
       
  1138 	{	
       
  1139 	TInt err=0;
       
  1140 	TInt k=0;
       
  1141 	TBuf<64> filename;
       
  1142 	CWriteFaxFile*  writeFaxFile;
       
  1143 	CReadFaxFile*   readFaxFile;
       
  1144 	TRawScanLine	decodedScanLine;
       
  1145 	//TFaxBufSenderId sd;
       
  1146 	TFaxBufSenderId senderId;
       
  1147 
       
  1148 
       
  1149 	writeFaxFile = CWriteFaxFile::NewL();
       
  1150 	CleanupStack::PushL(writeFaxFile);
       
  1151 	readFaxFile  = CReadFaxFile::NewL();
       
  1152 	CleanupStack::PushL(readFaxFile);
       
  1153 	iConverting=TRUE;
       
  1154 	
       
  1155 	TRAP (err,readFaxFile->OpenL(iSource->iOurFaxEntry.iFaxPageStore));
       
  1156 	if (err!=KErrNone)
       
  1157 		{
       
  1158 		iConverting=FALSE;
       
  1159 		User::Leave(err);
       
  1160 		}
       
  1161 
       
  1162  	readFaxFile->iReadFaxPages->SetPageL(0);
       
  1163 	TFaxPageInfo info = readFaxFile->iReadFaxPages->CurrentPageInfo();
       
  1164 	if (info.iCompression != EModifiedHuffman)
       
  1165 		User::Panic(_L("Not a 1D file"),1);
       
  1166 
       
  1167 	//writeFaxFile->OpenL(_L("c:\\blank2D.fax"),64);
       
  1168 	filename.Copy(iSource->iOurFaxEntry.iFaxPageStore);
       
  1169 	filename.Append(_L("2d"));
       
  1170 	// the second push in OpenL doesn't cause a double deletion of writeFaxFile, since it is pushed by using TCleanupItem.
       
  1171 	// coverity [double_push]
       
  1172 	writeFaxFile->OpenL(filename,64);
       
  1173 	//writeFaxFile->OpenL(iSource->iOurFaxEntry.iFaxPageStore,64);
       
  1174 	
       
  1175 
       
  1176 	for (k=0; k<iSource->iFaxPages; k++)
       
  1177 	{
       
  1178 	readFaxFile->iReadFaxPages->SetPageL(k);
       
  1179 	TFaxPageInfo info = readFaxFile->iReadFaxPages->CurrentPageInfo();
       
  1180 	if (info.iCompression != EModifiedHuffman)
       
  1181 		User::Panic(_L("Not a 1D file"),1);
       
  1182 	writeFaxFile->iWriteFaxPages->StartPage(info.iResolution, EModifiedRead);
       
  1183 	for (TInt n = info.iNumScanLines ; n  ; n--)
       
  1184 		{
       
  1185 		readFaxFile->iReadFaxPages->GetScanLineL(decodedScanLine);	
       
  1186 		writeFaxFile->iWriteFaxPages->AddScanLineL(decodedScanLine);
       
  1187 		}
       
  1188 
       
  1189 	writeFaxFile->iWriteFaxPages->EndPageL(info.iResolution,senderId, EModifiedRead);
       
  1190 	}// end of for statement
       
  1191 		
       
  1192 	writeFaxFile->CommitL();
       
  1193 	writeFaxFile->Close();
       
  1194 	readFaxFile->Close();
       
  1195 		
       
  1196 	AddSourceL(filename,Prefer2D);
       
  1197 	iFaxSessionSettings.iTxPages = (iSource->iFaxPages/2);	// sent only the 2d version of the document
       
  1198 															// which means half the attached pages
       
  1199 	CleanupStack::PopAndDestroy(2);
       
  1200 	iConverting=FALSE;
       
  1201 }	
       
  1202 
       
  1203 
       
  1204 
       
  1205 /***********************************************************************************/
       
  1206 // This function takes the received 2D file and converts it to 1D
       
  1207 // The 2D file will be deleted and the 1D version of the file will 
       
  1208 // inherit the name of the received 2D version
       
  1209 /************************************************************************************/
       
  1210 void CFaxTransfer::Convert1dL ()
       
  1211 	{	
       
  1212 	TInt err=0;
       
  1213 	TInt k=0;
       
  1214 	TBuf<64> filename;
       
  1215 	CWriteFaxFile* writeFaxFile;
       
  1216 	CReadFaxFile*  readFaxFile;
       
  1217 	TRawScanLine decodedScanLine;
       
  1218 	//TFaxBufSenderId sd;
       
  1219 	TFaxBufSenderId senderId;
       
  1220 
       
  1221 	writeFaxFile = CWriteFaxFile::NewL();
       
  1222 	CleanupStack::PushL(writeFaxFile);
       
  1223 	readFaxFile  = CReadFaxFile::NewL();
       
  1224 	CleanupStack::PushL(readFaxFile);	
       
  1225 	iConverting=TRUE;
       
  1226 
       
  1227 	//TRAP (err,readFaxFile->OpenL(iSource->iOurFaxEntry.iFaxPageStore));
       
  1228 	TRAP (err,readFaxFile->OpenL(iReceiveFileName));
       
  1229 	if (err!=KErrNone)
       
  1230 		User::Leave(err);
       
  1231 		
       
  1232  	readFaxFile->iReadFaxPages->SetPageL(0);
       
  1233 	TFaxPageInfo info = readFaxFile->iReadFaxPages->CurrentPageInfo();
       
  1234 	//if (info.iCompression != EModifiedHuffman)
       
  1235 	if (info.iCompression != EModifiedRead)
       
  1236 		User::Panic(_L("Not a 2D file"),1);
       
  1237 	
       
  1238 	//filename.Copy(iSource->iOurFaxEntry.iFaxPageStore);
       
  1239 	filename.Copy(iReceiveFileName);
       
  1240 	filename.Append(_L("1d"));
       
  1241 	// the second push in OpenL doesn't cause a double deletion of writeFaxFile, since it is pushed by using TCleanupItem.
       
  1242 	// coverity [double_push]
       
  1243 	writeFaxFile->OpenL(filename,64);
       
  1244 	//	writeFaxFile->OpenL(iSource->iOurFaxEntry.iFaxPageStore,64);
       
  1245 	
       
  1246 
       
  1247 	TInt iRxPages=readFaxFile->iReadFaxPages->NumPages();
       
  1248 
       
  1249 	for (k=0; k<iRxPages; k++)
       
  1250 	{
       
  1251 	readFaxFile->iReadFaxPages->SetPageL(k);
       
  1252 	TFaxPageInfo info = readFaxFile->iReadFaxPages->CurrentPageInfo();
       
  1253 	//if (info.iCompression != EModifiedHuffman)
       
  1254 	if (info.iCompression != EModifiedRead)
       
  1255 		User::Panic(_L("Not a 2D file"),1);
       
  1256 	//writeFaxFile->iWriteFaxPages->StartPage(info.iResolution, EModifiedRead);
       
  1257 	writeFaxFile->iWriteFaxPages->StartPage(info.iResolution, EModifiedHuffman);
       
  1258 	for (TInt n = info.iNumScanLines ; n  ; n--)
       
  1259 		{
       
  1260 		readFaxFile->iReadFaxPages->GetScanLineL(decodedScanLine);	
       
  1261 		writeFaxFile->iWriteFaxPages->AddScanLineL(decodedScanLine);
       
  1262 		}
       
  1263 
       
  1264 	//writeFaxFile->iWriteFaxPages->EndPageL(info.iResolution,senderId, EModifiedRead);
       
  1265 	writeFaxFile->iWriteFaxPages->EndPageL(info.iResolution,senderId, EModifiedHuffman);
       
  1266 	}// end of for statement
       
  1267 		
       
  1268 	writeFaxFile->CommitL();
       
  1269 	writeFaxFile->Close();
       
  1270 	readFaxFile->Close();
       
  1271 	
       
  1272 	RFs FileServer;
       
  1273 	err = FileServer.Connect();
       
  1274 	if (err !=KErrNone)
       
  1275 		User::Leave(err);
       
  1276 	User::LeaveIfError(FileServer.Delete(iReceiveFileName));
       
  1277 
       
  1278 	User::LeaveIfError(FileServer.Rename(filename,iReceiveFileName));
       
  1279 	
       
  1280 	FileServer.Close();
       
  1281 
       
  1282 	CleanupStack::PopAndDestroy(2);	
       
  1283 	iConverting=FALSE;
       
  1284 //	AddSourceL(filename,Prefer2D);
       
  1285 //	iFaxSessionSettings.iTxPages = (iSource->iFaxPages/2);	// sent only the 2d version of the document
       
  1286 	}	
       
  1287 
       
  1288 
       
  1289 /*
       
  1290 
       
  1291 CFaxTransfer::StartThread()
       
  1292 	{
       
  1293 	TInt state = KErrNone;
       
  1294 	TInt heapSize = 0x14000;	
       
  1295 	TInt stackSize = 0x14000;
       
  1296 
       
  1297 	reinterpret_cast<TAny*>(this);  // this points to a CFaxTransfer Object
       
  1298 	state = iConverterThread.Create ((_L ("FaxConverterThread")), FaxConverterThread, stackSize, heapSize, heapSize, this, EOwnerThread);
       
  1299 	if (state)
       
  1300 		{
       
  1301 		state = KFaxThreadError;
       
  1302 		}
       
  1303 	else
       
  1304 		{
       
  1305 		//aThreadStat = KRequestPending;
       
  1306 		//if (iClientCancel != KErrCancel)
       
  1307 		//iClientCancel = KRequestPending;
       
  1308 		//iDriverThread.Logon (aThreadStat);
       
  1309 		
       
  1310 		iConverterThread.SetPriority (EPriorityRealTime);
       
  1311 		iConverterThread.Resume ();
       
  1312 		}
       
  1313 	return state;
       
  1314 	}
       
  1315 
       
  1316 TInt FaxConverterThread (TAny * session)
       
  1317 	{
       
  1318 	TInt m;
       
  1319 	CTrapCleanup *cleanup = CTrapCleanup::New ();
       
  1320 	CFaxTransfer *faxtransfer =reinterpret_cast<CFaxTransfer *>(session);
       
  1321 	RSemaphore aSemaphore;
       
  1322 	TFindSemaphore mysemaphore(_L("FaxCli*"));
       
  1323 
       
  1324     TFullName      theName (_L("FaxCliSem"));
       
  1325 //  RSemaphore     theSem;             // derived from RHandleBase
       
  1326     
       
  1327   if ((mysemaphore.Next(theName))==KErrNone)
       
  1328         {
       
  1329         aSemaphore.Open(mysemaphore,EOwnerThread);
       
  1330         }
       
  1331 
       
  1332 
       
  1333 	TRAP(m,faxtransfer->Convert2dL());
       
  1334 
       
  1335 	aSemaphore.Signal();	
       
  1336 	return KErrNone;
       
  1337 	}
       
  1338 */