messagingappbase/obexmtms/obexmtm/obexserver/source/obexSendOp_debug.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 // Copyright (c) 2001-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 // $Workfile: obexSendOp_debug.cpp $
       
    15 // $Author: Stevep $
       
    16 // $Revision: 22 $
       
    17 // $Date: 25/03/02 10:52 $
       
    18 // 
       
    19 //
       
    20 
       
    21 //class include
       
    22 #include <obexsendop.h>
       
    23 
       
    24 #ifdef __OBEX_SEND_OP_FILE_DEBUG_MODE__
       
    25 #pragma message ("//")
       
    26 #pragma message ("//                                                                          //")
       
    27 #pragma message ("//                               FILE DEBUG MODE                            //")
       
    28 #pragma message ("//                                                                          //")
       
    29 #pragma message ("//")
       
    30 
       
    31 //System includes
       
    32 #include <msvids.h>
       
    33 #include <msventry.h>	//CMsvServerEntry
       
    34 #include <btmsgtypeuid.h>	//KUidMsgTypeBt
       
    35 #include <irmsgtypeuid.h>	//KUidMsgTypeIr
       
    36 //#include <obexpindlguid.h> //KObexPinNotifierUid
       
    37 
       
    38 //user includes
       
    39 // Following are named KErrIrObexClientXXXXX because they are using the irobex.dll (which 
       
    40 // should really be called obex.dll now that it supports more than IR)
       
    41 const TInt KErrIrObexClientPutPeerCannotHandleObject = -5504;
       
    42 const TInt KErrIrObexClientFirstPutFailed = -5510;
       
    43 const TInt KErrIrObexClientSubsequentPutFailed = -5511;
       
    44 
       
    45 _LIT(KObexFileDebugIRServiceFolder, "c:\\system\\obexdebug\\IRservice\\output");
       
    46 _LIT(KObexFileDebugBTServiceFolder, "c:\\system\\obexdebug\\BTservice\\output");
       
    47 _LIT(KObexFileDebugUSBServiceFolder, "c:\\system\\obexdebug\\USBservice\\output");
       
    48 _LIT(KOutputFileFormatString, "%S\\%d.obex");
       
    49 
       
    50 
       
    51 //
       
    52 //  CObexServerSendOperation....	CMsvOperation derived op that is intended to be owned by a CMsvReporterOperation or similar. 
       
    53 //							When this completes, the CMsvReporterOperation completes too
       
    54 //
       
    55 
       
    56 void CObexServerSendOperation::BuildSpecificConstructL()
       
    57 /**
       
    58 Debug second phase constructor. Sets the service path as appropriate to the MTM.
       
    59 */
       
    60 	{
       
    61 	//Connect to the file store
       
    62 	User::LeaveIfError(iServiceFs.Connect());
       
    63 
       
    64 	//select the output directory dependent upon the MTM being used
       
    65 	if (iMtm == KUidMsgTypeBt)
       
    66 		{
       
    67 		iServicePath = KObexFileDebugBTServiceFolder;
       
    68 		}
       
    69 	if (iMtm == KUidMsgTypeIrUID)
       
    70 		{
       
    71 		iServicePath = KObexFileDebugIRServiceFolder;
       
    72 		}
       
    73 	}
       
    74 
       
    75 void CObexServerSendOperation::BuildSpecificDestructor()
       
    76 /**
       
    77  * Destructor. Cancel()s, deletes owned objects and Close()s the connection to the FileServer.
       
    78  */
       
    79 	{
       
    80 	iServiceFs.Close();
       
    81 	}
       
    82 
       
    83 EXPORT_C const TDesC8& CObexServerSendOperation::ProgressL()
       
    84 /**
       
    85 Returns current progress information.
       
    86 
       
    87 @return A reference to a TPckgC<TObexMtmProgress> package pointer descriptor containing progress information on this send operation.
       
    88 @leave KErrXXX system wide error codes
       
    89 */
       
    90 	{
       
    91 	// State operation type (and progress).
       
    92 	TObexMtmProgress progress;
       
    93 
       
    94 	if (progress.iSendState != EInitialsed)
       
    95 		progress.iSendState=iSendState;
       
    96 	else
       
    97 		progress.iSendState = EInitialise;
       
    98 
       
    99 	progress.iTotalEntryCount = iAttachmentEntryCount + iFileNameEntryCount;
       
   100 	progress.iEntriesDone = progress.iTotalEntryCount - (iNextAttachment+1) - (iFileNameList? iFileNameList->Count() : 0);
       
   101 	progress.iCurrentEntrySize = 0; 
       
   102 	progress.iCurrentBytesTrans = 0;
       
   103 	progress.iError = iStatus.Int();
       
   104 
       
   105 	// prepate package buffer for return value, we copy it to a data member so progress
       
   106 	// data isn't destroyed when we go out of scope
       
   107 	TPckgC<TObexMtmProgress> progressDes(progress); 
       
   108     iProgressPckg.Copy(progressDes); //important to use copy() not set(), set() just points to our local descriptor 
       
   109 	return iProgressPckg;
       
   110 	}
       
   111 
       
   112 TInt CObexServerSendOperation::PutObexObjectToServiceFileL()
       
   113 /**
       
   114  * Output the obex object to a file in the service folder
       
   115  *
       
   116  * @leave KErrXXX system wide error codes
       
   117  */
       
   118 	{
       
   119 	//count the number of entries already in the folder
       
   120 	CDir* serviceDirectoryList = 0;
       
   121 	TFileName servicePath = iServicePath;
       
   122 	_LIT(KSlash, "\\");
       
   123 	servicePath.Append(KSlash);
       
   124 
       
   125 	//Close the file by Reset()ing the obex object--otherwise it can't be copied
       
   126 	iObexObject->Reset();
       
   127 
       
   128 	//copy a file to the service folder
       
   129 	CFileMan* fileMan = CFileMan::NewL(iServiceFs);
       
   130 	TInt err = fileMan->Copy(iSendFile, iServicePath);
       
   131 
       
   132 	//count the number of files
       
   133 	err = iServiceFs.GetDir(servicePath, KEntryAttNormal, ESortByName, serviceDirectoryList);
       
   134 	if (err != KErrNone)
       
   135 		{
       
   136 		ActivateRunLWithError(err);
       
   137 		}
       
   138 
       
   139 	//Create a new filename consisting of the service path followed by the new file number .obex
       
   140 	TFileName newFileName = iServicePath;
       
   141 	newFileName.Format(KOutputFileFormatString, &iServicePath, serviceDirectoryList->Count());
       
   142 
       
   143 	//No longer need serviceDirectoryList
       
   144 	delete serviceDirectoryList;
       
   145 
       
   146 	//Write the iObexObject member to the file
       
   147 	//err = iObexObject->WriteToFile(newFileName);
       
   148 
       
   149 
       
   150 	//Now rename it the file
       
   151 	//first make the original filename
       
   152 	TParse parser;
       
   153 	parser.Set(iSendFile, 0, 0);
       
   154 	servicePath.Append(parser.NameAndExt());	//servicePath now contains the full path and filename
       
   155 	//now actually rename it
       
   156 	err = fileMan->Rename(servicePath, newFileName);
       
   157 
       
   158 	delete fileMan;
       
   159 	return err;
       
   160 	}
       
   161 
       
   162 void CObexServerSendOperation::RealRunL()
       
   163 /**
       
   164 Implementation of the send operation state machine. Progresses as:
       
   165 
       
   166   Initialise-->Connect-->ConnectAttemptComplete-->SendObject-->(SendNextObject-->)SendComplete-->Disconnected
       
   167 
       
   168   The SendNextObject state is repeated for each attachment in excess of one. 
       
   169 
       
   170 Also handles UserCancelled and SendError states by CompleteObserver()ing with appropriate error codes.
       
   171 
       
   172   Leaves will be passed back to RunL and handled there. 
       
   173 
       
   174   @leave Leaves if insufficient memory.
       
   175   @leave Leaves if there is a file error when loading an object from a file
       
   176 */
       
   177 	{
       
   178 	const TInt status=iStatus.Int();
       
   179 
       
   180 	switch(iSendState)
       
   181 		{
       
   182 	case TObexMtmProgress::EInitialise://state 1
       
   183 		{
       
   184 		// Timeout for repeatedly trying to connect to remote OBEX device
       
   185 		iTimeoutTimer->After(iConnectTimeout);  
       
   186 
       
   187 		iSendState = TObexMtmProgress::EConnect;
       
   188 		SetActive();
       
   189 		CompleteSelf(KErrNone);
       
   190 		break;
       
   191 		}
       
   192 
       
   193 	case TObexMtmProgress::EConnect://state 2
       
   194 		{  
       
   195 		iSendState=TObexMtmProgress::EConnectAttemptComplete;
       
   196 		iStatus=KRequestPending;
       
   197 		SetActive();
       
   198 		CompleteSelf(KErrNone);
       
   199 		break;
       
   200 		}
       
   201 
       
   202 	case TObexMtmProgress::EConnectAttemptComplete://state 3
       
   203 		{
       
   204 		// A connection _attempt_ has completed - see if it was sucessful.
       
   205 		if (status == KErrNone)
       
   206 			{
       
   207 			// Ok - remote Obex device found and connected to
       
   208 			iTimeoutTimer->Cancel(); //cancel connect timeout
       
   209 			iSendState=TObexMtmProgress::ESendObject; //Go to send state
       
   210 			CompleteSelf(KErrNone);
       
   211 			}
       
   212 		else if( (status == KErrNotFound) || (status == KErrTimedOut) || (status == KErrIrObexClientNoDevicesFound) )
       
   213 			{  
       
   214 			// Connect failed. No remote device was found so we try again.
       
   215 			// (KErrIrObexClientNoDevicesFound is an OBEX specific error)
       
   216 			iSendState=TObexMtmProgress::EConnect; //return to connect state above
       
   217 			CompleteSelf(KErrNone);
       
   218 			}
       
   219 		else 
       
   220 			{
       
   221 			// KErrDisconnected = Found obex machine but had "Obex" IAS query failure.
       
   222 			// status>0  means that 'status' obex machines have been found.
       
   223 			// IAS Query is where the class of transport is not supported.
       
   224 			iTimeoutTimer->Cancel();
       
   225 			iSendState=TObexMtmProgress::ESendError;
       
   226 			CompleteSelf(status);
       
   227 			}
       
   228 		SetActive();
       
   229 		break;
       
   230 		}
       
   231 
       
   232 	case TObexMtmProgress::ESendObject://state 4
       
   233 	case TObexMtmProgress::ESendNextObject:  //state 5: Multiple object support.
       
   234 		{
       
   235 		iTimeoutTimer->Cancel(); // Cancel last timeout.
       
   236 
       
   237 		// For multiObject, check success of previous put. (Single objects won't be affected).
       
   238 		if(!CheckStatusOfLastObject (status, iSendState))
       
   239 			{
       
   240 			//Last message failed - CheckStatusOfLastObject has taken the necessary steps to notify
       
   241 			break;
       
   242 			}
       
   243 
       
   244 		//Get the next object ready to send
       
   245 		TInt err = PrepareCurrentObjectAndSetStateL();
       
   246 
       
   247 		SetActive();
       
   248 
       
   249 		//Check the status of preparation
       
   250 		if (err == KErrNone)
       
   251 			{
       
   252 			//Successful, so try to "send" it
       
   253 			iTimeoutTimer->After(iPutTimeout); // Start a new one.
       
   254 			CompleteSelf(PutObexObjectToServiceFileL());
       
   255 			}
       
   256 		else
       
   257 			{
       
   258 			//Unsuccessful--report the error
       
   259 			iTimeoutTimer->After(iPutTimeout); // Start a new one.
       
   260 			CompleteSelf(err);
       
   261 			}
       
   262 
       
   263 		break;
       
   264 		}
       
   265 
       
   266 	case TObexMtmProgress::ESendComplete://state 6
       
   267 		{
       
   268 		iTimeoutTimer->Cancel(); //cancel iPutTimeout
       
   269 
       
   270 		// Object "send(s)" have completed but latest might have completed with an error
       
   271 		if(!CheckStatusOfLastObject (status, iSendState))
       
   272 			{
       
   273 			//Last message failed - CheckStatusOfLastObject has taken the necessary steps to notify
       
   274 			break;
       
   275 			}
       
   276 
       
   277 		//Now attempt to move the successfully sent message to the sent folder
       
   278 		MoveToSentAndSetActiveL();
       
   279 		break;
       
   280 		}
       
   281 
       
   282 	case TObexMtmProgress::EMovedToSent://state 7
       
   283 		{
       
   284 		//Release the lock on the Sent folder, and mark the message as complete
       
   285 		CleanupAfterMovedToSent();
       
   286 
       
   287 		iSendState=TObexMtmProgress::EDisconnected;
       
   288 		SetActive();
       
   289 		CompleteSelf(KErrNone);
       
   290 
       
   291 		// Unfortunately, it is possible for this call to never complete if you send
       
   292 		// a file that the peer does not understand. This occurs because some peers 
       
   293 		// (i.e. Palm) don't seem able to handle this scenario correctly and don't 
       
   294 		// drop the transport when they should. So we restart the 'put' timeout to 
       
   295 		// catch this error
       
   296 		iTimeoutTimer->After(iPutTimeout);
       
   297 		}
       
   298 		break;
       
   299 
       
   300 	case TObexMtmProgress::EDisconnected://state 8
       
   301 		{
       
   302 		iTimeoutTimer->Cancel();
       
   303 		if(status != KErrNone)
       
   304 			{
       
   305 			// Pass error code onto the owner of this messaging operation
       
   306 			iSendState=TObexMtmProgress::ESendError;
       
   307 			SetActive();
       
   308 			CompleteSelf(status);
       
   309 			}
       
   310 		else
       
   311 			{
       
   312 			// Completed OK - 
       
   313 			// Signal MS that the CMsvOperation has ended, and clean up.
       
   314 			TObexMtmProgress& progress = iProgressPckg();
       
   315 			progress.iError = KErrNone;
       
   316 			CompleteObserver();
       
   317 			}
       
   318 		break;
       
   319 		}
       
   320 
       
   321 	case TObexMtmProgress::EUserCancelled://state 9
       
   322 		{  
       
   323 		// Signal that the CMsvOperation has been cancelled by the user.
       
   324 		TObexMtmProgress& progress = iProgressPckg();
       
   325 		progress.iError = KErrCancel;
       
   326 		iTimeoutTimer->Cancel();
       
   327 		CompleteObserver();
       
   328 		break;
       
   329 		}
       
   330 
       
   331 	case TObexMtmProgress::ESendError://state 10
       
   332 		{
       
   333 		// General error handling stage.
       
   334 		TObexMtmProgress& progress = iProgressPckg();
       
   335 		progress.iError = status;
       
   336 		iTimeoutTimer->Cancel();
       
   337 		CompleteObserver();
       
   338 		break;
       
   339 		}
       
   340 
       
   341 	default:
       
   342 		Panic(EObexSendOperationUnknownSendState);
       
   343 		}
       
   344 	}
       
   345 
       
   346 #endif	//__OBEX_SEND_OP_FILE_DEBUG_MODE__