smf/smfservermodule/smfclient/client/smfclientsymbian.cpp
changeset 7 be09cf1f39dd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smf/smfservermodule/smfclient/client/smfclientsymbian.cpp	Tue May 18 17:37:12 2010 +0530
@@ -0,0 +1,471 @@
+/**
+ * Copyright (c) 2010 Sasken Communication Technologies Ltd.
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the "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:
+ * Chandradeep Gandhi, Sasken Communication Technologies Ltd - Initial contribution
+ *
+ * Contributors:
+ * Manasij Roy, Nalina Hariharan
+ */
+
+#include "smfclientsymbian.h"
+#include <e32cmn.h>
+#include <QtGlobal>
+#include <e32svr.h>
+#include <e32base.h>
+#include <QByteArray>
+#include "smfglobal.h"
+#include "smfclientglobal.h"
+//testing purpose
+#include <QProcess>
+#include <QTextStream>
+#include <QFile>
+//testing end
+// For starting the server process
+static TInt StartServerL();
+static TInt CreateServerProcessL();
+
+CSmfClientSymbian::CSmfClientSymbian(smfObserver* aObserver)
+: iObserver(aObserver),CActive( EPriorityStandard ),iDataPtr(NULL, 0, 0)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CSmfClientSymbian* CSmfClientSymbian::NewL(smfObserver* aObserver )
+    {
+	CSmfClientSymbian* self = NewLC( aObserver );
+    CleanupStack::Pop( self );
+    return( self ) ;
+    }
+
+CSmfClientSymbian* CSmfClientSymbian::NewLC(smfObserver* aObserver )
+    {
+	CSmfClientSymbian* self =
+        new ( ELeave ) CSmfClientSymbian( aObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+void CSmfClientSymbian::ConstructL()
+    {
+	writeLog("CSmfClientSymbian::ConstructL");
+
+    User::LeaveIfError(iSession.connectToServer());
+    }
+void CSmfClientSymbian::writeLog(QString log) 
+	{
+#ifdef WRITE_LOG
+	QFile file("c:\\data\\SmfClientLogs.txt");
+    if (!file.open(QIODevice::Append | QIODevice::Text))
+	         return;
+    QTextStream out(&file);
+    out << log << "\n";
+    file.close();
+#endif
+	}
+
+void CSmfClientSymbian::DoCancel()
+	{
+	Cancel();
+	}
+
+TInt CSmfClientSymbian::RunError(TInt aError)
+	{
+	QString log2("CSmfClientSymbian::RunError=");
+	
+	log2 += QString::number(aError);
+	writeLog(log2);
+	return KErrNone;
+	}
+
+void CSmfClientSymbian::RunL()
+	{
+	QString log2("CSmfClientSymbian::RunL=");
+	log2 += QString::number(iStatus.Int());
+	writeLog(log2);
+    switch ( iStatus.Int() )
+        {
+        case KErrCancel:
+            // The request was canceled
+        	writeLog("KErrCancel");
+            break ;
+
+        case KErrNotReady:
+        	writeLog("KErrNotReady");
+        	break;
+
+        default:
+        	{
+        	writeLog("RunL:-SmfContactRetrievePostsComplete");
+        	//This contains error followed by actual data
+        	QByteArray receivedData(reinterpret_cast<const char*>(iSession.iDataPtr.Ptr()),iSession.iDataPtr.Length());
+        	QString errStr;
+        	SmfError errVal;
+        	int errInt;
+        	QByteArray data;
+        	QDataStream reader(&receivedData,QIODevice::ReadOnly);
+        	reader>>errInt;
+        	errVal = (SmfError)errInt;
+        	reader>>data;
+        	SmfRequestTypeID opcode = (SmfRequestTypeID)iSession.getLastRequest();
+        	iObserver->resultsAvailable(data,opcode,errVal);
+        	}
+        	break;
+        }
+	}
+
+QByteArray CSmfClientSymbian::sendRequest(QString aInterfaceName,
+		 SmfRequestTypeID requestType)
+	{
+	//This will be a synchronous request
+	//note session is opened in ctor and closed in dtor
+	writeLog("CSmfClientSymbian::sendRequest=");
+	writeLog(aInterfaceName);
+	//Gets data synchronously from the server
+    TPtr8 symbianBuf(iSession.sendSyncRequest(aInterfaceName,requestType));
+    //convert this into bytearray
+    QByteArray receivedData(reinterpret_cast<const char*>(symbianBuf.Ptr()),symbianBuf.Length());
+    return receivedData;
+    //
+	}
+
+TInt CSmfClientSymbian::sendRequest(QByteArray& aSerializedData,
+		 QString aInterfaceName,
+		 SmfRequestTypeID requestType)
+	{
+	//TODO:-testing puspose only, should be removed in the release
+	if(requestType == SmfTest)
+		{
+		QString log("Before iSesson.SendAsync");
+		writeLog(log);
+		iSession.sendAsyncRequest(aSerializedData,aInterfaceName,requestType,iStatus);
+		SetActive();
+		QString log2("After setactive");
+		writeLog(log2);
+		}
+	else
+		{
+		//RSessionBase objects sendreceive is called
+		iSession.sendAsyncRequest(aSerializedData,aInterfaceName,requestType,iStatus);
+		SetActive();
+		}
+	}
+
+TInt CSmfClientSymbian::sendDummyRequest(QByteArray* provider,QString aInterfaceName,
+		 SmfRequestTypeID requestType)
+	{
+	switch(requestType)
+		{
+		case SmfTest:
+			{
+
+			}
+			break;
+		default:
+			//should panic
+			break;
+		}
+	}
+
+CSmfClientSymbian::~CSmfClientSymbian()
+	{
+	writeLog("~CSmfClientSymbian");
+    Cancel(); // Causes call to DoCancel()
+    iSession.Close();
+	}
+
+RSmfClientSymbianSession::RSmfClientSymbianSession()
+:iDataPtr(NULL, 0, 0),iDataPtr16(NULL,0),iIntfNamePtr(NULL,0),iIntfNamePtr8(NULL,0),iPtrProvider(NULL,0)
+    {
+    // No implementation required
+    }
+
+TInt RSmfClientSymbianSession::connectToServer()
+    {
+	writeLog("RSmfClientSymbianSession::connectToServer");
+    TInt error = ::StartServerL();
+    writeLog("StartServerL=");
+    QString err = QString::number(error);
+    writeLog(err);
+    if ( KErrNone == error )
+        {
+		
+        error = CreateSession( KSmfServerName,
+                               Version(),
+                               4 );
+        QString crtSessionErr = QString::number(error);
+        writeLog(crtSessionErr);
+        }
+    return error;
+    }
+
+//testing
+void RSmfClientSymbianSession::writeLog(QString log) const
+	{
+#ifdef WRITE_LOG
+	QFile file("c:\\data\\SmfClientLogs.txt");
+    if (!file.open(QIODevice::Append | QIODevice::Text))
+	         ;
+    QTextStream out(&file);
+    out << log << "\n";
+    file.close();
+#endif
+	}
+
+TPtr8 RSmfClientSymbianSession::sendSyncRequest(QString aInterfaceName,
+		SmfRequestTypeID aRequestType)
+	{
+	iLastRequest = aRequestType;
+	/**
+	 * The message body consists of.- 
+	 * 1. Interface name as string ("org.symbian.smf.client.gallery")
+	 * 2. Data pointer to be filled by serialized data(QList<smfProvider>)
+	 */
+	QString log("RSmfClientSymbianSession::sendSyncRequest-start-");
+	writeLog(log);
+	writeLog(QString("aInterfaceName=")+aInterfaceName);
+	
+	iInterfaceNamebyte.clear();
+	//Convert the interface name into TPtr
+	iInterfaceName.clear();
+	iInterfaceName = aInterfaceName ;
+	writeLog(QString("iInterfaceName=")+iInterfaceName);
+	//lets pass serialized QString
+	QDataStream intfNameStream(&iInterfaceNamebyte,QIODevice::WriteOnly);
+	intfNameStream<<iInterfaceName;
+	log.clear();
+    log = QString("iInterfaceNamebyte size=");
+    log += QString::number(iInterfaceNamebyte.size());
+    writeLog(log);
+	if(iIntfNameBuffer8)
+		{
+		delete iIntfNameBuffer8;
+		iIntfNameBuffer8 =NULL;
+		}
+	TInt serializedintfsize = iInterfaceNamebyte.size();
+	writeLog("iInterfaceNamebyte.size()=");
+	writeLog(QString::number(serializedintfsize));
+	iIntfNameBuffer8 = HBufC8::NewL(iInterfaceNamebyte.size()*2);
+	iIntfNamePtr8.Set(iIntfNameBuffer8->Des());
+	iIntfNamePtr8.Copy(reinterpret_cast<TUint8*>(iInterfaceNamebyte.data()),iInterfaceNamebyte.length());
+	log.clear();
+    log = QString("iIntfNamePtr8 size=")+QString::number(iIntfNamePtr8.Size());
+    writeLog(log);
+
+    writeLog("Before provider symbian copy");
+	
+	
+	iInterfaceSymbian8.Copy(iIntfNamePtr8);	
+	if(iBuffer)
+		{
+		delete iBuffer;
+		iBuffer = NULL;
+		}
+	iMaxMessageSize = 1000 ;
+    iBuffer = HBufC8::NewL(iMaxMessageSize);
+    iDataPtr.Set(iBuffer->Des());
+    log.clear();
+    log = QString("After iDataPtr.Set");
+    writeLog(log);
+
+	
+    TIpcArgs args;
+
+    args.Set(0, &iInterfaceSymbian8);
+    args.Set(1, &iDataPtr);
+    
+    TInt err(KErrBadHandle);
+    writeLog("Before handle");
+	log.clear();
+    log = QString("iInterfaceSymbian8 size=")+QString::number(iInterfaceSymbian8.Size());
+    writeLog(log);
+    if (Handle()) 
+    	{
+        err = KErrNone;
+        log.clear();
+        log = QString("Before sendreceive");
+        writeLog(log);
+        //synchronous request
+        TInt sendErr = SendReceive(aRequestType, args);
+        if(sendErr)
+        	{
+			writeLog("SendReceive error=");
+			QString errStr = QString::number(sendErr);
+			writeLog(errStr);
+        	}
+        return iDataPtr;
+        }
+	}
+
+/**
+ * Calls SendReceive() after converting into symbian descriptors
+ *
+ */
+void RSmfClientSymbianSession::sendAsyncRequest(QByteArray& aSerializedData,
+		QString aInterfaceName,
+		SmfRequestTypeID aRequestType,
+		TRequestStatus& aStatus)
+	{
+	iLastRequest = aRequestType;
+	/**
+	 * The message body consists of.- 
+	 * 1. Provider Info(SmfProvider*)+ Other common class data
+	 *  (when applicable)-serialized
+	 * 2. Interface name as string ("org.symbian.smf.client.gallery")
+	 * 3. Data pointer to be filled by serialized data
+	 */
+	QString log("RSmfClientSymbianSession::sendAsyncRequest-start-");
+	writeLog(log);
+	
+	iBaseProvider= aSerializedData;
+	iInterfaceName = aInterfaceName ;
+	
+    int size = aSerializedData.size();
+    log.clear();
+    log = QString("aSerializedData size=")+ QString::number(size);
+    
+    writeLog(log);
+    if(iProviderBuf)
+    	{
+		delete iProviderBuf;
+		iProviderBuf = NULL;
+    	}
+    //TODO:- KSmfProviderMaxSize
+    iProviderBuf = HBufC8::NewL(iBaseProvider.size()*2);
+    iPtrProvider.Set(iProviderBuf->Des());
+	//convert the QByteArray into TPtr
+    iPtrProvider.Copy(reinterpret_cast<const TText8*>(iBaseProvider.constData()),iBaseProvider.length());
+    
+	
+    log.clear();
+    log = QString("iPtrProvider.Copy");
+    writeLog(log);
+    
+	//Convert the interface name into TPtr////////////////////////
+	iInterfaceName.clear();
+	iInterfaceName = aInterfaceName ;
+	writeLog(QString("iInterfaceName=")+iInterfaceName);
+	//Pass serialized QString for interface name
+	QDataStream intfNameStream(&iInterfaceNamebyte,QIODevice::WriteOnly);
+	intfNameStream<<iInterfaceName;
+	log.clear();
+    log = QString("iInterfaceNamebyte size=");
+    log += QString::number(iInterfaceNamebyte.size());
+    writeLog(log);
+	if(iIntfNameBuffer8)
+		{
+		delete iIntfNameBuffer8;
+		iIntfNameBuffer8 =NULL;
+		}
+	iIntfNameBuffer8 = HBufC8::NewL(aInterfaceName.size()*2);
+	iIntfNamePtr8.Set(iIntfNameBuffer8->Des());
+	//Convert into symbian data type
+	iIntfNamePtr8.Copy(reinterpret_cast<TUint8*>(iInterfaceNamebyte.data()),iInterfaceNamebyte.length());
+	log.clear();
+    log = QString("iIntfNamePtr8 size=")+QString::number(iIntfNamePtr8.Size());
+    writeLog(log);
+	
+
+	if(iBuffer)
+		{
+		delete iBuffer;
+		iBuffer = NULL;
+		}
+	//TODO:-KSmfMaxDataSize
+	iMaxMessageSize = 2000 ;
+    iBuffer = HBufC8::NewL(iMaxMessageSize);
+    iDataPtr.Set(iBuffer->Des());
+    log.clear();
+    log = QString("After iDataPtr.Set");
+    writeLog(log);
+	
+	
+    TIpcArgs args;
+    
+
+    args.Set(0, &iPtrProvider);
+    args.Set(1, &iIntfNamePtr8);
+    args.Set(2, &iDataPtr);
+    
+    TInt err(KErrBadHandle);
+    log.clear();
+    log = QString("Before Handle()");
+    writeLog("Before handle");
+    if (Handle()) 
+    	{
+        err = KErrNone;
+        log.clear();
+        log = QString("Before sendreceive");
+        writeLog(log);
+       SendReceive(aRequestType, args, aStatus);
+
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// StartServerL()
+// Starts the server if it is not already running
+// -----------------------------------------------------------------------------
+//
+static TInt StartServerL()
+    {
+    TInt result;
+
+    TFindServer findSmfServer( KSmfServerName );
+    TFullName name;
+
+    result = findSmfServer.Next( name );
+    if ( result == KErrNone )
+        {
+        // Server already running
+        return KErrNone;
+        }
+
+    result = CreateServerProcessL();
+    if ( result != KErrNone )
+        {
+        return  result;
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CreateServerProcessL()
+// Creates a server process
+// -----------------------------------------------------------------------------
+//
+static TInt CreateServerProcessL()
+    {
+    TInt result;
+    //SmfServer SID
+    TUid KSmfServerUID3 = { 0xE5027327 };
+    const TUidType serverUid( KNullUid, KNullUid, KSmfServerUID3 );
+
+    RProcess server;
+
+    result = server.Create( KSmfServerFilename, KNullDesC, serverUid );
+    User::LeaveIfError(result);
+    if (KErrNone != result) {
+        return  result; 
+    }
+    else {
+		//User::WaitForRequest going for infinite loop, temporary work-around
+        //TRequestStatus status;
+        //server.Rendezvous(status);
+        server.Resume(); // logon OK - start the server
+        //Going for infinite loop
+        //User::WaitForRequest(status);// wait for start or death
+        User::After(700000);
+        server.Close();
+        return KErrNone;
+        //return status.Int(); // return the error
+    }
+    return  KErrNone;
+    }