diff -r 000000000000 -r 96612d01cf9f videofeeds/clientapi/src/RIptvClientSession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videofeeds/clientapi/src/RIptvClientSession.cpp Mon Jan 18 20:21:12 2010 +0200 @@ -0,0 +1,320 @@ +/* +* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 FILES +#include +#include + +#include "MIptvStreamObject.h" +#include +#include +#include "IptvDebug.h" + +#include "IptvClientServerCommon.h" +#include "CIptvService.h" +#include "CIptvServiceManager.h" +#include "RIptvClientSession.h" + +// FUNCTION PROTOTYPES +static TInt StartServer(); +static TInt CreateServerProcess(); + +// CONSTANTS +const TUint KDefaultMessageSlots = 20; +const TInt KIptvServerFreeSpace = 512000; // 500 KB + +// ========================= MEMBER FUNCTIONS ================================== + +// ----------------------------------------------------------------------------- +// RIptvClientSession::RIptvClientSession() +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C RIptvClientSession::RIptvClientSession() +: RSessionBase(), iIpcMessagePtr((unsigned char*)0, 0) + { + // No implementation required + } + +EXPORT_C RIptvClientSession::~RIptvClientSession() + { + delete iIpcMessage; + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::Connect() +// Connects to the server and create a session. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RIptvClientSession::Connect() + { + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::Connect()"); + + const TInt KOneSecondDelay = 1000000; + const TInt KMaxRetries = 10; + + TInt error = TryConnect(); + TInt retryCounter = 0; + + while (error != KErrNone) + { + // In OoM case we stop trying. Otherwise other errors would hide the real reason for failure. + if (error == KErrNoMemory) + { + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession:: failed to connect to server, out of memory."); + break; + } + // In case of "KErrNotFound" or "Server Terminated", we might be out of disk on + // first start-up. To make sure check the available disk space here on client side. + else if (error == KErrNotFound || error == KErrServerTerminated || error == KErrDiskFull) + { + RFs fsSession; + if (fsSession.Connect() == KErrNone) + { + TBool checkResult = EFalse; + TRAPD(checkError, checkResult = SysUtil::DiskSpaceBelowCriticalLevelL(&fsSession, KIptvServerFreeSpace, EDriveC)); + fsSession.Close(); + + if (checkError != KErrNone || checkResult) + { + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::Connect() returning KErrDiskFull"); + return KErrDiskFull; + } + } + } + + retryCounter++; + if(retryCounter > KMaxRetries) + { + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession:: failed to connect to server, giving up"); + break; + } + + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession:: failed to connect to server, retrying after 1 second"); + User::After(KOneSecondDelay); + + error = TryConnect(); + } + + IPTVLOGSTRING2_LOW_LEVEL("RIptvClientSession:: returning %d", error); + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::Connect() exit"); + return error; + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::TryConnect() +// Connects to the server and creates a session. +// ----------------------------------------------------------------------------- +// +TInt RIptvClientSession::TryConnect() + { + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::TryConnect()"); + + TInt error; + + error = ::StartServer(); + + if (error != KErrNone) + { + IPTVLOGSTRING2_LOW_LEVEL("RIptvClientSession:: failed to start server process: %d", error); + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::TryConnect() exit"); + return error; + } + + error = CreateSession( KIptvServerName, + Version(), + KDefaultMessageSlots ); + + if (error != KErrNone) + { + IPTVLOGSTRING2_LOW_LEVEL("RIptvClientSession:: failed to create session: %d", error); + } + + IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::TryConnect() exit"); + return error; + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::Version() +// Gets the version number. +// ----------------------------------------------------------------------------- +// +EXPORT_C TVersion RIptvClientSession::Version() const + { + return( TVersion( KIptvServMajorVersionNumber, + KIptvServMinorVersionNumber, + KIptvServBuildVersionNumber ) ); + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::IsNull() +// ----------------------------------------------------------------------------- +// +TBool RIptvClientSession::IsNull() const + { + return iHandle == NULL; + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::SendRequest() +// Issues a request to the server asynchronously. +// ----------------------------------------------------------------------------- +// +EXPORT_C void RIptvClientSession::SendRequest(TUint8 aMsgId, + TDes8& aMsg, + TRequestStatus& aStatus) + { + TIpcArgs ipcArgs(&aMsg); + SendReceive(aMsgId, ipcArgs, aStatus); + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::SendRequest() +// Issues a request to the server synchronously. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RIptvClientSession::SendRequest(TUint8 aMsgId, + TDes8& aMsg) + { + TIpcArgs ipcArgs(&aMsg); + return SendReceive(aMsgId, ipcArgs); + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::SendRequest() +// Issues a request to the server. +// ----------------------------------------------------------------------------- +// +EXPORT_C void RIptvClientSession::SendRequest(TUint8 aMsgId, + TRequestStatus& aStatus) + { + SendReceive(aMsgId, aStatus); + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::SendRequest() +// Send synchrounous request to server. +// ----------------------------------------------------------------------------- +EXPORT_C TInt RIptvClientSession::SendRequest(TUint8 aMsgId) const + { + return SendReceive(aMsgId, TIpcArgs()); + } + +// ----------------------------------------------------------------------------- +// RIptvClientSession::SendRequest() +// Issues a request to the server synchronously. +// ----------------------------------------------------------------------------- +// +TInt RIptvClientSession::SendRequest( TUint8 aMsgId, + TIpcArgs& aArgs ) const + { + return SendReceive( aMsgId, aArgs); + } + + +// ============================= OTHER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// StartServer() +// Starts the server if it is not already running +// ----------------------------------------------------------------------------- +// +static TInt StartServer() + { + + TInt result; + + TFindServer findIptvServer( KIptvServerName ); + TFullName name; + + result = findIptvServer.Next( name ); + if ( result == KErrNone ) + { + // Server already running + return KErrNone; + } + + RSemaphore semaphore; + result = semaphore.CreateGlobal( KIptvServerSemaphoreName,0 ,EOwnerProcess); + + if(result != KErrNone) + { + IPTVLOGSTRING2_HIGH_LEVEL("Failed to create semaphore, reason: %d", result); + return result; + } + + IPTVLOGSTRING_HIGH_LEVEL("Client created semaphore, init value 0"); + + result = CreateServerProcess(); + if(result != KErrNone) + { + IPTVLOGSTRING2_HIGH_LEVEL("Failed to start server, reason: %d", result); + return result; + } + + //Decrease semaphore by 1. + //If semaphore is negative this thread is suspended until server signals. + //If server has already signalled, we don't stop at all. + //Server increases semaphore by 1 (with semaphore.Signal()) when it's running. + //Result is that this thread will wait here until server has signalled. + //Signalling may also happen before this thread gets to semaphore.Wait(). + IPTVLOGSTRING_LOW_LEVEL("client waiting semaphore"); + semaphore.Wait(); + IPTVLOGSTRING_LOW_LEVEL("client finished waiting semaphore"); + IPTVLOGSTRING_LOW_LEVEL("Now we can be sure that server is running..."); + + semaphore.Close(); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CreateServerProcess() +// Creates the Iptv Engine server process +// ----------------------------------------------------------------------------- +// +static TInt CreateServerProcess() + { + IPTVLOGSTRING_LOW_LEVEL("CreateServerProcess()"); + + TUid uid1 = { 0x1000007a }; + TUid uid2 = { /*0x1000008d*/ 0x00000000 }; + + const TUidType serverUid(uid1, /*KNullUid*/uid2, KIptvEngineServerUid3 ); + + TInt result; + RProcess server; + result = server.Create(KIptvServerFileName, KIptvEmptyDes, EOwnerProcess); + + if(result != KErrNone) + { + IPTVLOGSTRING_LOW_LEVEL("CreateServerProcess() failed to create process"); + } + else + { + server.Resume(); + server.Close(); + } + + IPTVLOGSTRING_LOW_LEVEL("CreateServerProcess() exit"); + return result; + } + +// End of File