smf/smfservermodule/smfclient/client/smfclientsymbian.cpp
author cgandhi <chandradeep.gandhi@sasken.com>
Tue, 18 May 2010 17:37:12 +0530
changeset 7 be09cf1f39dd
permissions -rw-r--r--
Updating the source code for plugin manager, transport manager, smfserver and smf client.

/**
 * 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;
    }