videofeeds/clientapi/src/RIptvClientSession.cpp
changeset 0 96612d01cf9f
--- /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