usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexServer.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <e32base.h>
       
    19 #include <obexconstants.h>
       
    20 
       
    21 #include "simpleObexServer.h"
       
    22 #include "simpleObexApp.h"
       
    23 #include "obexAppConstants.h"
       
    24 
       
    25 
       
    26 /**
       
    27  * Constructor.
       
    28  */
       
    29 CObexServerHandler::CObexServerHandler(CActiveConsole* aParent)
       
    30 :iAcceptPuts(ETrue)
       
    31     {
       
    32 	iParent = aParent;
       
    33     iServer    = NULL;
       
    34     iObject    = NULL;
       
    35     }
       
    36 
       
    37 
       
    38 
       
    39 /**
       
    40  * NewL function
       
    41  */
       
    42 CObexServerHandler* CObexServerHandler::NewL(CActiveConsole* aParent, TTransport aTransport)
       
    43     {
       
    44     CObexServerHandler* self = new (ELeave) CObexServerHandler(aParent);
       
    45 
       
    46     CleanupStack::PushL(self);
       
    47     self->ConstructL(aTransport);
       
    48     CleanupStack::Pop();
       
    49     return (self);
       
    50     }
       
    51 
       
    52 
       
    53 /**
       
    54  * 2nd phase constructor. This function performs the initial steps needed in 
       
    55  * creating a new CObexServer object. It then creates the CObexServer object for the specified
       
    56  * transport.
       
    57  *
       
    58  */
       
    59 void CObexServerHandler::ConstructL(TTransport aTransport)
       
    60     {
       
    61 	iTransportLayer = aTransport;
       
    62 	if (aTransport == EBluetooth)
       
    63 		{
       
    64 		// Start bluetooth socket and set security
       
    65 		RSocketServ socketServ;
       
    66 		socketServ.Connect();
       
    67 		RSocket listen;
       
    68 		TInt test = listen.Open(socketServ, KRFCOMMDesC);
       
    69 
       
    70 		if (test == KErrNone)
       
    71 			{
       
    72 			iParent->Console()->Printf(_L("Socket Open ... Success\n"));	
       
    73 			}
       
    74 
       
    75 		TBTSockAddr addr;
       
    76 		// Auto bind to RFComm port
       
    77 		addr.SetPort(KRfcommPassiveAutoBind);
       
    78 		
       
    79 		TBTServiceSecurity serviceSecurity;
       
    80 			
       
    81 		serviceSecurity.SetUid(KUidServiceSDP);
       
    82 		serviceSecurity.SetAuthentication(EFalse);
       
    83 		serviceSecurity.SetEncryption(EFalse);
       
    84 		serviceSecurity.SetAuthorisation(EFalse);
       
    85 		serviceSecurity.SetDenied(EFalse);
       
    86 		addr.SetSecurity(serviceSecurity);
       
    87 			
       
    88 		TInt error;	
       
    89 		// Set bluetooth protocol info
       
    90 		TObexBluetoothProtocolInfo info;
       
    91 		info.iAddr.SetPort(KObexTestPort);
       
    92 		info.iTransport = KRFCOMMDesC;
       
    93 		TRAP(error,iServer  = CObexServer::NewL(info));
       
    94 		if (error)
       
    95 			{
       
    96 			iParent->Console()->Printf(_L("\r\n Could not create obex server! : error %d \r\n"),error);
       
    97 			iParent->iMode = E_Inactive;
       
    98 			iParent->iMode = E_Server;
       
    99 			iParent->Cancel(); // cancel request for key
       
   100 			}
       
   101 		// Add services to the Service discovery database
       
   102 			
       
   103 		User::LeaveIfError(iSdp.Connect());
       
   104 		User::LeaveIfError(iSdpdb.Open(iSdp));
       
   105 		
       
   106 		TSdpServRecordHandle ftphandle;
       
   107 
       
   108 		iSdpdb.CreateServiceRecordL(ftpUuid, ftphandle);
       
   109 		iSdpdb.UpdateAttributeL(ftphandle, KSdpAttrIdServiceName, KServerDesC);
       
   110 				
       
   111 		iProtDescList = CSdpAttrValueDES::NewDESL(0);
       
   112 
       
   113 			iProtDescList
       
   114 			->StartListL()
       
   115 				->BuildDESL()
       
   116 				->StartListL()
       
   117 					->BuildUUIDL(KL2CAPUUID) 
       
   118 				->EndListL()
       
   119 				->BuildDESL()
       
   120 				->StartListL()
       
   121 					->BuildUUIDL(KRfcommUuid) 
       
   122 						->BuildUintL(TSdpIntBuf<TInt8>(KObexTestPort))
       
   123 				->EndListL()
       
   124 				->BuildDESL()
       
   125 				->StartListL()
       
   126 					->BuildUUIDL(KObexProtocolUuid) 
       
   127 				->EndListL()
       
   128 			->EndListL();
       
   129 		// Update attribute
       
   130 		iSdpdb.UpdateAttributeL(ftphandle, KProtocolDescriptorListUUID, *iProtDescList); // put into both records
       
   131 		delete iProtDescList;
       
   132 			
       
   133 		User::LeaveIfError(listen.Bind(addr)); 
       
   134 			
       
   135 		TInt queueSize=2;
       
   136 		User::LeaveIfError(listen.Listen(queueSize));
       
   137 	
       
   138 		iParent->Console()->Printf(_L("\n.....Now Listening.....\n"));
       
   139 		
       
   140 		}
       
   141 
       
   142 	else if (aTransport == EIrda)
       
   143 		{
       
   144 		
       
   145 		//creating the transport info
       
   146 		TObexIrProtocolInfo transportInfo;
       
   147 		transportInfo.iAddr.SetPort(KAutoBindLSAP);//default obex server for now
       
   148 		transportInfo.iTransport = KObexIrTTPProtocol; 
       
   149 		transportInfo.iClassName      = KIrdaClassName;					
       
   150 		transportInfo.iAttributeName = KIrdaTransportAttrName;
       
   151 
       
   152   		iServer = CObexServer::NewL (transportInfo);
       
   153 		
       
   154 		}
       
   155 	
       
   156     else if (aTransport == EWin32Usb)
       
   157 		{
       
   158 		// Create transport info
       
   159 		TObexUsbProtocolInfo aInfo;
       
   160 		aInfo.iTransport = KObexWin32UsbProtocol;
       
   161         aInfo.iInterfaceStringDescriptor = KServerInterfaceDescriptor;
       
   162 		iServer = CObexServer::NewL (aInfo);
       
   163 		
       
   164 		}
       
   165    
       
   166    // Now that the transport has been selected and Obex Server started
       
   167    // We need to do some initialisation with Obex Objects so that we are 
       
   168    // prepared to deal with Put/Get requests from the client
       
   169     
       
   170     iObject  = CObexBufObject::NewL (NULL);
       
   171 
       
   172     iBuf = CBufFlat::NewL(KServerBufExpandSize);
       
   173   	
       
   174 	iBuf->ResizeL(KServerBufExpandSize);// Resize the buffer
       
   175 
       
   176 	iObject = CObexBufObject::NewL(NULL);
       
   177 	iObject->SetDataBufL(iBuf);
       
   178 	//Create the RFile to be used
       
   179 	User::LeaveIfError(iFs.Connect());
       
   180 	User::LeaveIfError(iFs.CreatePrivatePath(EDriveC));
       
   181 	User::LeaveIfError(iFs.SetSessionToPrivate(EDriveC));
       
   182 	User::LeaveIfError(iFs.SessionPath( iSessionPath ));
       
   183 	// Start the server
       
   184 	User::LeaveIfError(iServer->Start (this)); 
       
   185     
       
   186     }
       
   187 
       
   188 
       
   189 
       
   190 
       
   191 /**
       
   192  * This function stops the OBEX server
       
   193  */
       
   194 void CObexServerHandler::Stop()
       
   195     {
       
   196 	if (iServer)
       
   197 		{
       
   198 		iServer->Stop();
       
   199 		}
       
   200     }
       
   201 
       
   202 
       
   203 /**
       
   204  * Destructor.
       
   205  */
       
   206 CObexServerHandler::~CObexServerHandler ()
       
   207     {
       
   208     Stop();
       
   209 	
       
   210 	iSdpdb.Close();
       
   211 	iSdp.Close();
       
   212 
       
   213 	delete iObject;
       
   214     delete iBuf;
       
   215     delete iServer;
       
   216     }
       
   217 
       
   218 /**
       
   219  * This function enables authentication on the OBEX server.
       
   220  * The password is defined in source.
       
   221  */
       
   222 void CObexServerHandler::EnableAuthenticationL()
       
   223 	{
       
   224 	iChallengePassword = KAuthPassword;
       
   225 	iServer->SetChallengeL(iChallengePassword);
       
   226 	iIsAuthenticationEnabled = ETrue;
       
   227 	}
       
   228 
       
   229 /**
       
   230  * This function disables authentication on the server.
       
   231  */
       
   232 void CObexServerHandler::DisableAuthentication()
       
   233 	{
       
   234 	iServer->ResetChallenge();
       
   235 	iIsAuthenticationEnabled = EFalse;
       
   236 	}
       
   237 
       
   238 
       
   239 
       
   240 
       
   241 
       
   242 // MObexServerNotify interface functions
       
   243 
       
   244 /**
       
   245  * Called if an OBEX protocol error occurs.
       
   246  */
       
   247 void CObexServerHandler::ErrorIndication (TInt aError)
       
   248     {
       
   249     iParent->Console()->Printf(_L("Obex Server error %d"), aError);
       
   250     }
       
   251 
       
   252 /**
       
   253  * Called when the underlying transport connection is made from a remote client to the server.
       
   254  */
       
   255 void CObexServerHandler::TransportUpIndication ()
       
   256     {
       
   257     iParent->Console()->Printf(_L("\nTransport started\n"));
       
   258     }
       
   259 
       
   260 /**
       
   261  * Called when the transport connection is dropped (by either party).
       
   262  */
       
   263 void CObexServerHandler::TransportDownIndication ()
       
   264     {
       
   265     iParent->Console()->Printf(_L("\nTransport down\n"));
       
   266     }
       
   267 
       
   268 /**
       
   269  * Called when an OBEX connection is made from a remote client.
       
   270  */
       
   271 TInt CObexServerHandler::ObexConnectIndication(const TObexConnectInfo& aRemoteInfo, const TDesC8& /*aInfo*/)
       
   272     {
       
   273     
       
   274     iParent->Console()->Printf(_L("\r\nCObexServerHandler::ObexConnectIndication"));
       
   275 	iParent->Console()->Printf(_L("\r\nConnected to machine with OBEX version %d.%d\r\n"), 
       
   276 		     aRemoteInfo.VersionMajor (), aRemoteInfo.VersionMinor ());
       
   277 
       
   278      return (KErrNone);
       
   279     
       
   280     }
       
   281 
       
   282 /**
       
   283  * Called on a (graceful) OBEX disconnection by the client.
       
   284  */
       
   285 void CObexServerHandler::ObexDisconnectIndication (const TDesC8& /*aInfo*/)
       
   286     {
       
   287     iParent->Console()->Printf(_L("\r\nObex Disconnected\r\n\r\n"));
       
   288     }
       
   289 
       
   290 
       
   291 /**
       
   292  * Called on receipt of the first packet of a (valid) put request.
       
   293  */
       
   294 CObexBufObject* CObexServerHandler::PutRequestIndication ()
       
   295     {
       
   296     iParent->Console()->Printf(_L("Receiving object...\r\n"));
       
   297     iObject->Reset ();
       
   298 
       
   299 	if ( iAcceptPuts)
       
   300 		return (iObject);
       
   301 	else
       
   302 		return (NULL);
       
   303     }
       
   304 
       
   305 /**
       
   306  * Called on receipt of every packet of an OBEX PUT operation.
       
   307  */
       
   308 TInt CObexServerHandler::PutPacketIndication ()
       
   309     {
       
   310     
       
   311     TUint length = iObject->Length();
       
   312 
       
   313 	TUint received = iObject->BytesReceived();
       
   314 	TUint8 percent = 0;
       
   315     if (length > 0)
       
   316 		{
       
   317 		percent = TUint8((100 * received) / length);
       
   318 		iParent->Console()->Printf(_L("\r%d %%      "), percent);
       
   319 		}
       
   320     else
       
   321 		{
       
   322 		iParent->Console()->Printf(_L("\r%d      "), iObject->BytesReceived ());
       
   323 		}
       
   324     return (KErrNone);
       
   325     
       
   326     }
       
   327 
       
   328 /**
       
   329  * Called after the final put packet has been successfully received and parsed.
       
   330  */
       
   331 TInt CObexServerHandler::PutCompleteIndication ()
       
   332     {
       
   333     TPtrC name=iObject->Name();
       
   334 	TBuf<100> type;
       
   335 	type.Copy(iObject->Type());
       
   336 	iParent->Console()->Printf(_L("\r\nSuccessfully received '%S'\r\nType[%d]: '%S'\r\n"), &name, type.Length(), &type);
       
   337 
       
   338 	TInt err = KErrNone;
       
   339 	TBuf<80> filename(iSessionPath);
       
   340 	filename.Append(iObject->Name());
       
   341 	err = iObject->WriteToFile(filename);
       
   342     if (err == KErrAlreadyExists)
       
   343     	{
       
   344        	iParent->Console()->Printf(_L("\r\nWrite failed, File Already Exists\n"));
       
   345         }
       
   346     
       
   347 	iObject->Reset ();
       
   348     return (err);
       
   349     }
       
   350 
       
   351 
       
   352 /**
       
   353  * Called when a full get request has been received from the client.
       
   354  */
       
   355 CObexBufObject* CObexServerHandler::GetRequestIndication (CObexBaseObject* aRequiredObject)
       
   356     {
       
   357 
       
   358 	TRAPD(err,SetUpGetObjectL(aRequiredObject));
       
   359 	if (err != KErrNone)
       
   360 		{
       
   361 		iParent->Console()->Printf(_L("\nSetUpGetObjectL() returned %d.\n"), err);
       
   362 		return NULL;
       
   363 		}
       
   364 		
       
   365 	return (iObject);
       
   366 	
       
   367 	}
       
   368 	
       
   369 	
       
   370 /**
       
   371  * Called for every packet of get reply sent by the server back to the client.
       
   372  */
       
   373 TInt CObexServerHandler::GetPacketIndication ()
       
   374     {
       
   375     if (iObject->Length () > 0)
       
   376 		iParent->Console()->Printf(_L("\r%d %%      "), 
       
   377 			 100 * iObject->BytesSent () / iObject->Length ());
       
   378     else
       
   379 		iParent->Console()->Printf(_L("\r%d Bytes      "), iObject->BytesSent ());
       
   380     return (KErrNone);
       
   381     }
       
   382 
       
   383 /**
       
   384  * Called when the final packet of the object has been returned to the client.
       
   385  */
       
   386 TInt CObexServerHandler::GetCompleteIndication ()
       
   387     {
       
   388     iParent->Console()->Printf(_L("Obex Get Complete\r\n"));
       
   389     iObject->Reset ();
       
   390 	return (KErrNone);
       
   391     }
       
   392     
       
   393     
       
   394     
       
   395 /**
       
   396  * Called when an OBEX SETPATH command is received by the server.
       
   397  *
       
   398  */
       
   399 TInt CObexServerHandler::SetPathIndication (const CObex::TSetPathInfo& aPathInfo, const TDesC8& /*aInfo*/)
       
   400     {
       
   401     iParent->Console()->Printf(_L("Obex SetPath request:\r\n"));
       
   402     iParent->Console()->Printf(_L("   --- Flags = '%d' - Constants = '%d' - "), aPathInfo.iFlags, aPathInfo.iConstants);
       
   403     
       
   404     if (aPathInfo.iNamePresent)
       
   405 		iParent->Console()->Printf(_L("Name = %S\r\n"), &aPathInfo.iName);
       
   406 	else
       
   407 		iParent->Console()->Printf(_L("> No Name Present <\r\n"));
       
   408 	
       
   409 	iParent->Console()->Printf(_L("\nReturning success...!\n"));
       
   410 	return (KErrNone);
       
   411     
       
   412     }
       
   413 
       
   414 /**
       
   415  * Called when an abort packet is received from the client.
       
   416  */
       
   417 void CObexServerHandler::AbortIndication ()
       
   418     {
       
   419     iParent->Console()->Printf(_L("Obex Operation aborted\r\n"));
       
   420     if(iObject)
       
   421 		{
       
   422 		// Determine if we have recieved any amount of the object
       
   423 		// Return without notifing user if we haven't.
       
   424 		if(!iObject->BytesReceived())
       
   425 		    return;
       
   426 		iParent->Console()->Printf(_L("\r\nWe have received part of an Obex object\r\n\r\n"));
       
   427 
       
   428 		iObject->Reset();
       
   429 		}
       
   430 	}
       
   431 
       
   432 
       
   433 /**
       
   434  * This is the function that sets up an object ready for a Get.
       
   435  * It takes as a parameter the requested object and then examines it's
       
   436  * name and if a filename matches then the object it setup from that file.
       
   437  */
       
   438 void CObexServerHandler::SetUpGetObjectL(CObexBaseObject *aRequestedObject)
       
   439 	{
       
   440 	// Get the name of the requested object
       
   441 	TBuf<200> name (aRequestedObject->Name ());
       
   442 	if(name.Length())
       
   443 		{
       
   444 		iParent->Console()->Printf(_L("Obex Get Request for name '%s'\r\n"), name.PtrZ ());
       
   445 		}
       
   446 
       
   447 	else
       
   448 		{
       
   449 		iParent->Console()->Printf(_L("Obex Get Request unknown details\r\n"));
       
   450 		User::Leave(KErrNotSupported);
       
   451 		}
       
   452 	iObject->Reset();
       
   453 
       
   454 	RFs fs;
       
   455 	RFile f;
       
   456 	// Attempt to open the specified file
       
   457 	if ((fs.Connect () != KErrNone) || 
       
   458 		(f.Open (fs, name, EFileShareReadersOnly | EFileRead) != KErrNone))
       
   459 		{
       
   460 		iParent->Console()->Printf(_L("\r\nError reading '%S'."), &name);
       
   461 		User::Leave(KErrNotFound);
       
   462 		}
       
   463 	// We can now proceed in setting up the object using the file retrieved
       
   464 	
       
   465 	TInt size = 0;
       
   466 	// Set size of file
       
   467 	User::LeaveIfError(f.Size (size));
       
   468 	// Resize buffer object
       
   469 	iBuf->ResizeL(size);
       
   470 	// Get a pointer to represent the data
       
   471 	TInt bufStart=0;
       
   472 	TPtr8 data (iBuf->Ptr(bufStart));
       
   473 	// Read data from file,
       
   474 	f.Read (data);
       
   475 	if (iBuf->Size() < size)
       
   476 		User::Leave(KErrGeneral);
       
   477 	// Set name of the object
       
   478 	iObject->SetNameL(name);
       
   479 	// Set length
       
   480 	iObject->SetLengthL(size);
       
   481 	TTime time;
       
   482 	if (f.Modified(time) == KErrNone)
       
   483 		iObject->SetTimeL(time);
       
   484 	}