usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexServer.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/ObexClassController/test/src/simpleObexServer.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,484 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <e32base.h>
+#include <obexconstants.h>
+
+#include "simpleObexServer.h"
+#include "simpleObexApp.h"
+#include "obexAppConstants.h"
+
+
+/**
+ * Constructor.
+ */
+CObexServerHandler::CObexServerHandler(CActiveConsole* aParent)
+:iAcceptPuts(ETrue)
+    {
+	iParent = aParent;
+    iServer    = NULL;
+    iObject    = NULL;
+    }
+
+
+
+/**
+ * NewL function
+ */
+CObexServerHandler* CObexServerHandler::NewL(CActiveConsole* aParent, TTransport aTransport)
+    {
+    CObexServerHandler* self = new (ELeave) CObexServerHandler(aParent);
+
+    CleanupStack::PushL(self);
+    self->ConstructL(aTransport);
+    CleanupStack::Pop();
+    return (self);
+    }
+
+
+/**
+ * 2nd phase constructor. This function performs the initial steps needed in 
+ * creating a new CObexServer object. It then creates the CObexServer object for the specified
+ * transport.
+ *
+ */
+void CObexServerHandler::ConstructL(TTransport aTransport)
+    {
+	iTransportLayer = aTransport;
+	if (aTransport == EBluetooth)
+		{
+		// Start bluetooth socket and set security
+		RSocketServ socketServ;
+		socketServ.Connect();
+		RSocket listen;
+		TInt test = listen.Open(socketServ, KRFCOMMDesC);
+
+		if (test == KErrNone)
+			{
+			iParent->Console()->Printf(_L("Socket Open ... Success\n"));	
+			}
+
+		TBTSockAddr addr;
+		// Auto bind to RFComm port
+		addr.SetPort(KRfcommPassiveAutoBind);
+		
+		TBTServiceSecurity serviceSecurity;
+			
+		serviceSecurity.SetUid(KUidServiceSDP);
+		serviceSecurity.SetAuthentication(EFalse);
+		serviceSecurity.SetEncryption(EFalse);
+		serviceSecurity.SetAuthorisation(EFalse);
+		serviceSecurity.SetDenied(EFalse);
+		addr.SetSecurity(serviceSecurity);
+			
+		TInt error;	
+		// Set bluetooth protocol info
+		TObexBluetoothProtocolInfo info;
+		info.iAddr.SetPort(KObexTestPort);
+		info.iTransport = KRFCOMMDesC;
+		TRAP(error,iServer  = CObexServer::NewL(info));
+		if (error)
+			{
+			iParent->Console()->Printf(_L("\r\n Could not create obex server! : error %d \r\n"),error);
+			iParent->iMode = E_Inactive;
+			iParent->iMode = E_Server;
+			iParent->Cancel(); // cancel request for key
+			}
+		// Add services to the Service discovery database
+			
+		User::LeaveIfError(iSdp.Connect());
+		User::LeaveIfError(iSdpdb.Open(iSdp));
+		
+		TSdpServRecordHandle ftphandle;
+
+		iSdpdb.CreateServiceRecordL(ftpUuid, ftphandle);
+		iSdpdb.UpdateAttributeL(ftphandle, KSdpAttrIdServiceName, KServerDesC);
+				
+		iProtDescList = CSdpAttrValueDES::NewDESL(0);
+
+			iProtDescList
+			->StartListL()
+				->BuildDESL()
+				->StartListL()
+					->BuildUUIDL(KL2CAPUUID) 
+				->EndListL()
+				->BuildDESL()
+				->StartListL()
+					->BuildUUIDL(KRfcommUuid) 
+						->BuildUintL(TSdpIntBuf<TInt8>(KObexTestPort))
+				->EndListL()
+				->BuildDESL()
+				->StartListL()
+					->BuildUUIDL(KObexProtocolUuid) 
+				->EndListL()
+			->EndListL();
+		// Update attribute
+		iSdpdb.UpdateAttributeL(ftphandle, KProtocolDescriptorListUUID, *iProtDescList); // put into both records
+		delete iProtDescList;
+			
+		User::LeaveIfError(listen.Bind(addr)); 
+			
+		TInt queueSize=2;
+		User::LeaveIfError(listen.Listen(queueSize));
+	
+		iParent->Console()->Printf(_L("\n.....Now Listening.....\n"));
+		
+		}
+
+	else if (aTransport == EIrda)
+		{
+		
+		//creating the transport info
+		TObexIrProtocolInfo transportInfo;
+		transportInfo.iAddr.SetPort(KAutoBindLSAP);//default obex server for now
+		transportInfo.iTransport = KObexIrTTPProtocol; 
+		transportInfo.iClassName      = KIrdaClassName;					
+		transportInfo.iAttributeName = KIrdaTransportAttrName;
+
+  		iServer = CObexServer::NewL (transportInfo);
+		
+		}
+	
+    else if (aTransport == EWin32Usb)
+		{
+		// Create transport info
+		TObexUsbProtocolInfo aInfo;
+		aInfo.iTransport = KObexWin32UsbProtocol;
+        aInfo.iInterfaceStringDescriptor = KServerInterfaceDescriptor;
+		iServer = CObexServer::NewL (aInfo);
+		
+		}
+   
+   // Now that the transport has been selected and Obex Server started
+   // We need to do some initialisation with Obex Objects so that we are 
+   // prepared to deal with Put/Get requests from the client
+    
+    iObject  = CObexBufObject::NewL (NULL);
+
+    iBuf = CBufFlat::NewL(KServerBufExpandSize);
+  	
+	iBuf->ResizeL(KServerBufExpandSize);// Resize the buffer
+
+	iObject = CObexBufObject::NewL(NULL);
+	iObject->SetDataBufL(iBuf);
+	//Create the RFile to be used
+	User::LeaveIfError(iFs.Connect());
+	User::LeaveIfError(iFs.CreatePrivatePath(EDriveC));
+	User::LeaveIfError(iFs.SetSessionToPrivate(EDriveC));
+	User::LeaveIfError(iFs.SessionPath( iSessionPath ));
+	// Start the server
+	User::LeaveIfError(iServer->Start (this)); 
+    
+    }
+
+
+
+
+/**
+ * This function stops the OBEX server
+ */
+void CObexServerHandler::Stop()
+    {
+	if (iServer)
+		{
+		iServer->Stop();
+		}
+    }
+
+
+/**
+ * Destructor.
+ */
+CObexServerHandler::~CObexServerHandler ()
+    {
+    Stop();
+	
+	iSdpdb.Close();
+	iSdp.Close();
+
+	delete iObject;
+    delete iBuf;
+    delete iServer;
+    }
+
+/**
+ * This function enables authentication on the OBEX server.
+ * The password is defined in source.
+ */
+void CObexServerHandler::EnableAuthenticationL()
+	{
+	iChallengePassword = KAuthPassword;
+	iServer->SetChallengeL(iChallengePassword);
+	iIsAuthenticationEnabled = ETrue;
+	}
+
+/**
+ * This function disables authentication on the server.
+ */
+void CObexServerHandler::DisableAuthentication()
+	{
+	iServer->ResetChallenge();
+	iIsAuthenticationEnabled = EFalse;
+	}
+
+
+
+
+
+// MObexServerNotify interface functions
+
+/**
+ * Called if an OBEX protocol error occurs.
+ */
+void CObexServerHandler::ErrorIndication (TInt aError)
+    {
+    iParent->Console()->Printf(_L("Obex Server error %d"), aError);
+    }
+
+/**
+ * Called when the underlying transport connection is made from a remote client to the server.
+ */
+void CObexServerHandler::TransportUpIndication ()
+    {
+    iParent->Console()->Printf(_L("\nTransport started\n"));
+    }
+
+/**
+ * Called when the transport connection is dropped (by either party).
+ */
+void CObexServerHandler::TransportDownIndication ()
+    {
+    iParent->Console()->Printf(_L("\nTransport down\n"));
+    }
+
+/**
+ * Called when an OBEX connection is made from a remote client.
+ */
+TInt CObexServerHandler::ObexConnectIndication(const TObexConnectInfo& aRemoteInfo, const TDesC8& /*aInfo*/)
+    {
+    
+    iParent->Console()->Printf(_L("\r\nCObexServerHandler::ObexConnectIndication"));
+	iParent->Console()->Printf(_L("\r\nConnected to machine with OBEX version %d.%d\r\n"), 
+		     aRemoteInfo.VersionMajor (), aRemoteInfo.VersionMinor ());
+
+     return (KErrNone);
+    
+    }
+
+/**
+ * Called on a (graceful) OBEX disconnection by the client.
+ */
+void CObexServerHandler::ObexDisconnectIndication (const TDesC8& /*aInfo*/)
+    {
+    iParent->Console()->Printf(_L("\r\nObex Disconnected\r\n\r\n"));
+    }
+
+
+/**
+ * Called on receipt of the first packet of a (valid) put request.
+ */
+CObexBufObject* CObexServerHandler::PutRequestIndication ()
+    {
+    iParent->Console()->Printf(_L("Receiving object...\r\n"));
+    iObject->Reset ();
+
+	if ( iAcceptPuts)
+		return (iObject);
+	else
+		return (NULL);
+    }
+
+/**
+ * Called on receipt of every packet of an OBEX PUT operation.
+ */
+TInt CObexServerHandler::PutPacketIndication ()
+    {
+    
+    TUint length = iObject->Length();
+
+	TUint received = iObject->BytesReceived();
+	TUint8 percent = 0;
+    if (length > 0)
+		{
+		percent = TUint8((100 * received) / length);
+		iParent->Console()->Printf(_L("\r%d %%      "), percent);
+		}
+    else
+		{
+		iParent->Console()->Printf(_L("\r%d      "), iObject->BytesReceived ());
+		}
+    return (KErrNone);
+    
+    }
+
+/**
+ * Called after the final put packet has been successfully received and parsed.
+ */
+TInt CObexServerHandler::PutCompleteIndication ()
+    {
+    TPtrC name=iObject->Name();
+	TBuf<100> type;
+	type.Copy(iObject->Type());
+	iParent->Console()->Printf(_L("\r\nSuccessfully received '%S'\r\nType[%d]: '%S'\r\n"), &name, type.Length(), &type);
+
+	TInt err = KErrNone;
+	TBuf<80> filename(iSessionPath);
+	filename.Append(iObject->Name());
+	err = iObject->WriteToFile(filename);
+    if (err == KErrAlreadyExists)
+    	{
+       	iParent->Console()->Printf(_L("\r\nWrite failed, File Already Exists\n"));
+        }
+    
+	iObject->Reset ();
+    return (err);
+    }
+
+
+/**
+ * Called when a full get request has been received from the client.
+ */
+CObexBufObject* CObexServerHandler::GetRequestIndication (CObexBaseObject* aRequiredObject)
+    {
+
+	TRAPD(err,SetUpGetObjectL(aRequiredObject));
+	if (err != KErrNone)
+		{
+		iParent->Console()->Printf(_L("\nSetUpGetObjectL() returned %d.\n"), err);
+		return NULL;
+		}
+		
+	return (iObject);
+	
+	}
+	
+	
+/**
+ * Called for every packet of get reply sent by the server back to the client.
+ */
+TInt CObexServerHandler::GetPacketIndication ()
+    {
+    if (iObject->Length () > 0)
+		iParent->Console()->Printf(_L("\r%d %%      "), 
+			 100 * iObject->BytesSent () / iObject->Length ());
+    else
+		iParent->Console()->Printf(_L("\r%d Bytes      "), iObject->BytesSent ());
+    return (KErrNone);
+    }
+
+/**
+ * Called when the final packet of the object has been returned to the client.
+ */
+TInt CObexServerHandler::GetCompleteIndication ()
+    {
+    iParent->Console()->Printf(_L("Obex Get Complete\r\n"));
+    iObject->Reset ();
+	return (KErrNone);
+    }
+    
+    
+    
+/**
+ * Called when an OBEX SETPATH command is received by the server.
+ *
+ */
+TInt CObexServerHandler::SetPathIndication (const CObex::TSetPathInfo& aPathInfo, const TDesC8& /*aInfo*/)
+    {
+    iParent->Console()->Printf(_L("Obex SetPath request:\r\n"));
+    iParent->Console()->Printf(_L("   --- Flags = '%d' - Constants = '%d' - "), aPathInfo.iFlags, aPathInfo.iConstants);
+    
+    if (aPathInfo.iNamePresent)
+		iParent->Console()->Printf(_L("Name = %S\r\n"), &aPathInfo.iName);
+	else
+		iParent->Console()->Printf(_L("> No Name Present <\r\n"));
+	
+	iParent->Console()->Printf(_L("\nReturning success...!\n"));
+	return (KErrNone);
+    
+    }
+
+/**
+ * Called when an abort packet is received from the client.
+ */
+void CObexServerHandler::AbortIndication ()
+    {
+    iParent->Console()->Printf(_L("Obex Operation aborted\r\n"));
+    if(iObject)
+		{
+		// Determine if we have recieved any amount of the object
+		// Return without notifing user if we haven't.
+		if(!iObject->BytesReceived())
+		    return;
+		iParent->Console()->Printf(_L("\r\nWe have received part of an Obex object\r\n\r\n"));
+
+		iObject->Reset();
+		}
+	}
+
+
+/**
+ * This is the function that sets up an object ready for a Get.
+ * It takes as a parameter the requested object and then examines it's
+ * name and if a filename matches then the object it setup from that file.
+ */
+void CObexServerHandler::SetUpGetObjectL(CObexBaseObject *aRequestedObject)
+	{
+	// Get the name of the requested object
+	TBuf<200> name (aRequestedObject->Name ());
+	if(name.Length())
+		{
+		iParent->Console()->Printf(_L("Obex Get Request for name '%s'\r\n"), name.PtrZ ());
+		}
+
+	else
+		{
+		iParent->Console()->Printf(_L("Obex Get Request unknown details\r\n"));
+		User::Leave(KErrNotSupported);
+		}
+	iObject->Reset();
+
+	RFs fs;
+	RFile f;
+	// Attempt to open the specified file
+	if ((fs.Connect () != KErrNone) || 
+		(f.Open (fs, name, EFileShareReadersOnly | EFileRead) != KErrNone))
+		{
+		iParent->Console()->Printf(_L("\r\nError reading '%S'."), &name);
+		User::Leave(KErrNotFound);
+		}
+	// We can now proceed in setting up the object using the file retrieved
+	
+	TInt size = 0;
+	// Set size of file
+	User::LeaveIfError(f.Size (size));
+	// Resize buffer object
+	iBuf->ResizeL(size);
+	// Get a pointer to represent the data
+	TInt bufStart=0;
+	TPtr8 data (iBuf->Ptr(bufStart));
+	// Read data from file,
+	f.Read (data);
+	if (iBuf->Size() < size)
+		User::Leave(KErrGeneral);
+	// Set name of the object
+	iObject->SetNameL(name);
+	// Set length
+	iObject->SetLengthL(size);
+	TTime time;
+	if (f.Modified(time) == KErrNone)
+		iObject->SetTimeL(time);
+	}