--- /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 <e32math.h>
+#include <e32svr.h>
+
+#include "MIptvStreamObject.h"
+#include <sysutil.h>
+#include <f32file.h>
+#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