videofeeds/clientapi/src/RIptvClientSession.cpp
branchRCL_3
changeset 23 befca0ec475f
parent 0 96612d01cf9f
equal deleted inserted replaced
22:839377eedc2b 23:befca0ec475f
       
     1 /*
       
     2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <e32math.h>
       
    23 #include <e32svr.h>
       
    24 
       
    25 #include "MIptvStreamObject.h"
       
    26 #include <sysutil.h> 
       
    27 #include <f32file.h>
       
    28 #include "IptvDebug.h"
       
    29 
       
    30 #include "IptvClientServerCommon.h"
       
    31 #include "CIptvService.h"
       
    32 #include "CIptvServiceManager.h"
       
    33 #include "RIptvClientSession.h"
       
    34 
       
    35 // FUNCTION PROTOTYPES
       
    36 static TInt StartServer();
       
    37 static TInt CreateServerProcess();
       
    38 
       
    39 // CONSTANTS
       
    40 const TUint KDefaultMessageSlots = 20;
       
    41 const TInt KIptvServerFreeSpace = 512000; // 500 KB
       
    42 
       
    43 // ========================= MEMBER FUNCTIONS ==================================
       
    44 
       
    45 // -----------------------------------------------------------------------------
       
    46 // RIptvClientSession::RIptvClientSession()
       
    47 // C++ default constructor can NOT contain any code, that might leave.
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 EXPORT_C RIptvClientSession::RIptvClientSession()
       
    51 : RSessionBase(), iIpcMessagePtr((unsigned char*)0, 0)
       
    52     {
       
    53     // No implementation required
       
    54     }
       
    55 
       
    56 EXPORT_C RIptvClientSession::~RIptvClientSession()
       
    57     {
       
    58     delete iIpcMessage;
       
    59     }
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // RIptvClientSession::Connect()
       
    63 // Connects to the server and create a session.
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 EXPORT_C TInt RIptvClientSession::Connect()
       
    67     {
       
    68     IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::Connect()");
       
    69     
       
    70     const TInt KOneSecondDelay = 1000000;
       
    71     const TInt KMaxRetries     = 10;
       
    72 
       
    73     TInt error        = TryConnect();
       
    74     TInt retryCounter = 0;
       
    75 
       
    76     while (error != KErrNone)
       
    77         {
       
    78         // In OoM case we stop trying. Otherwise other errors would hide the real reason for failure.
       
    79         if (error == KErrNoMemory)
       
    80             {
       
    81             IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession:: failed to connect to server, out of memory.");
       
    82             break;
       
    83             }
       
    84         // In case of "KErrNotFound" or "Server Terminated", we might be out of disk  on
       
    85         // first start-up. To make sure check the available disk space here on client side.
       
    86         else if (error == KErrNotFound || error == KErrServerTerminated || error == KErrDiskFull)
       
    87             {
       
    88             RFs fsSession;
       
    89             if (fsSession.Connect() == KErrNone)
       
    90                 {
       
    91                 TBool checkResult = EFalse;
       
    92                 TRAPD(checkError, checkResult = SysUtil::DiskSpaceBelowCriticalLevelL(&fsSession, KIptvServerFreeSpace, EDriveC));
       
    93                 fsSession.Close();
       
    94 
       
    95                 if (checkError != KErrNone || checkResult)
       
    96                     {
       
    97                     IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::Connect() returning KErrDiskFull");
       
    98                     return KErrDiskFull;
       
    99                     }
       
   100                 }
       
   101             }
       
   102 
       
   103         retryCounter++;
       
   104         if(retryCounter > KMaxRetries)
       
   105             {
       
   106             IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession:: failed to connect to server, giving up");
       
   107             break;
       
   108             }
       
   109 
       
   110         IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession:: failed to connect to server, retrying after 1 second");
       
   111         User::After(KOneSecondDelay);
       
   112 
       
   113         error = TryConnect();
       
   114         }    
       
   115 
       
   116     IPTVLOGSTRING2_LOW_LEVEL("RIptvClientSession:: returning %d", error);        
       
   117     IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::Connect() exit");
       
   118     return error;
       
   119     }
       
   120     
       
   121 // -----------------------------------------------------------------------------
       
   122 // RIptvClientSession::TryConnect()
       
   123 // Connects to the server and creates a session.
       
   124 // -----------------------------------------------------------------------------
       
   125 //
       
   126 TInt RIptvClientSession::TryConnect()
       
   127     {
       
   128     IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::TryConnect()");
       
   129 
       
   130     TInt error;
       
   131 
       
   132     error = ::StartServer();
       
   133     
       
   134     if (error != KErrNone)
       
   135         {
       
   136         IPTVLOGSTRING2_LOW_LEVEL("RIptvClientSession:: failed to start server process: %d", error);
       
   137         IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::TryConnect() exit");
       
   138         return error;
       
   139         }
       
   140 	      
       
   141     error = CreateSession( KIptvServerName,
       
   142                            Version(),
       
   143                            KDefaultMessageSlots );
       
   144 
       
   145     if (error != KErrNone)
       
   146         {
       
   147         IPTVLOGSTRING2_LOW_LEVEL("RIptvClientSession:: failed to create session: %d", error);
       
   148         }
       
   149 
       
   150     IPTVLOGSTRING_LOW_LEVEL("RIptvClientSession::TryConnect() exit");
       
   151     return error;
       
   152     }
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 // RIptvClientSession::Version()
       
   156 // Gets the version number.
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 EXPORT_C TVersion RIptvClientSession::Version() const
       
   160     {
       
   161     return( TVersion( KIptvServMajorVersionNumber,
       
   162                       KIptvServMinorVersionNumber,
       
   163                       KIptvServBuildVersionNumber ) );
       
   164     }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // RIptvClientSession::IsNull()
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 TBool RIptvClientSession::IsNull() const
       
   171     {
       
   172     return iHandle == NULL;
       
   173     }
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 // RIptvClientSession::SendRequest()
       
   177 // Issues a request to the server asynchronously.
       
   178 // -----------------------------------------------------------------------------
       
   179 //
       
   180 EXPORT_C void RIptvClientSession::SendRequest(TUint8 aMsgId,
       
   181                                               TDes8& aMsg,
       
   182         							                        TRequestStatus& aStatus)
       
   183     {
       
   184     TIpcArgs ipcArgs(&aMsg);
       
   185     SendReceive(aMsgId, ipcArgs, aStatus);
       
   186     }
       
   187 
       
   188 // -----------------------------------------------------------------------------
       
   189 // RIptvClientSession::SendRequest()
       
   190 // Issues a request to the server synchronously.
       
   191 // -----------------------------------------------------------------------------
       
   192 //
       
   193 EXPORT_C TInt RIptvClientSession::SendRequest(TUint8 aMsgId,
       
   194                                               TDes8& aMsg)
       
   195     {
       
   196     TIpcArgs ipcArgs(&aMsg);
       
   197     return SendReceive(aMsgId, ipcArgs);
       
   198     }
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // RIptvClientSession::SendRequest()
       
   202 // Issues a request to the server.
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 EXPORT_C void RIptvClientSession::SendRequest(TUint8 aMsgId,
       
   206         							                        TRequestStatus& aStatus)
       
   207     {
       
   208     SendReceive(aMsgId, aStatus);
       
   209     }
       
   210 
       
   211 // -----------------------------------------------------------------------------
       
   212 // RIptvClientSession::SendRequest()
       
   213 // Send synchrounous request to server.
       
   214 // -----------------------------------------------------------------------------
       
   215 EXPORT_C TInt RIptvClientSession::SendRequest(TUint8 aMsgId) const
       
   216     {
       
   217     return SendReceive(aMsgId, TIpcArgs());
       
   218     }
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // RIptvClientSession::SendRequest()
       
   222 // Issues a request to the server synchronously.
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 TInt RIptvClientSession::SendRequest( TUint8 aMsgId,
       
   226                                       TIpcArgs& aArgs ) const
       
   227     {
       
   228     return SendReceive( aMsgId, aArgs);
       
   229     }
       
   230 
       
   231 
       
   232 // ============================= OTHER FUNCTIONS ===============================
       
   233 
       
   234 // -----------------------------------------------------------------------------
       
   235 // StartServer()
       
   236 // Starts the server if it is not already running
       
   237 // -----------------------------------------------------------------------------
       
   238 //
       
   239 static TInt StartServer()
       
   240     {
       
   241 
       
   242     TInt result;
       
   243 
       
   244     TFindServer findIptvServer( KIptvServerName );
       
   245     TFullName name;
       
   246 
       
   247     result = findIptvServer.Next( name );
       
   248     if ( result == KErrNone )
       
   249         {
       
   250         // Server already running
       
   251         return KErrNone;
       
   252         }
       
   253 
       
   254     RSemaphore semaphore;
       
   255     result = semaphore.CreateGlobal( KIptvServerSemaphoreName,0 ,EOwnerProcess);
       
   256 
       
   257     if(result != KErrNone)
       
   258         {
       
   259         IPTVLOGSTRING2_HIGH_LEVEL("Failed to create semaphore, reason: %d", result);
       
   260         return  result;
       
   261         }
       
   262 
       
   263     IPTVLOGSTRING_HIGH_LEVEL("Client created semaphore, init value 0");
       
   264 
       
   265     result = CreateServerProcess();
       
   266     if(result != KErrNone)
       
   267         {
       
   268         IPTVLOGSTRING2_HIGH_LEVEL("Failed to start server, reason: %d", result);
       
   269         return  result;
       
   270         }
       
   271 
       
   272     //Decrease semaphore by 1.
       
   273     //If semaphore is negative this thread is suspended until server signals.
       
   274     //If server has already signalled, we don't stop at all.
       
   275     //Server increases semaphore by 1 (with semaphore.Signal()) when it's running.
       
   276     //Result is that this thread will wait here until server has signalled.
       
   277     //Signalling may also happen before this thread gets to semaphore.Wait().
       
   278     IPTVLOGSTRING_LOW_LEVEL("client waiting semaphore");
       
   279     semaphore.Wait();
       
   280     IPTVLOGSTRING_LOW_LEVEL("client finished waiting semaphore");
       
   281     IPTVLOGSTRING_LOW_LEVEL("Now we can be sure that server is running...");
       
   282 
       
   283     semaphore.Close();
       
   284 
       
   285     return KErrNone;
       
   286     }
       
   287 
       
   288 // -----------------------------------------------------------------------------
       
   289 // CreateServerProcess()
       
   290 // Creates the Iptv Engine server process
       
   291 // -----------------------------------------------------------------------------
       
   292 //
       
   293 static TInt CreateServerProcess()
       
   294     {
       
   295     IPTVLOGSTRING_LOW_LEVEL("CreateServerProcess()");
       
   296     
       
   297     TUid uid1 = { 0x1000007a };
       
   298     TUid uid2 = { /*0x1000008d*/ 0x00000000 };
       
   299 	
       
   300     const TUidType serverUid(uid1, /*KNullUid*/uid2, KIptvEngineServerUid3 );
       
   301 
       
   302     TInt result;		
       
   303     RProcess server;
       
   304     result = server.Create(KIptvServerFileName, KIptvEmptyDes, EOwnerProcess);
       
   305     
       
   306     if(result != KErrNone)
       
   307         {
       
   308         IPTVLOGSTRING_LOW_LEVEL("CreateServerProcess() failed to create process");
       
   309         }
       
   310     else
       
   311         {
       
   312         server.Resume();
       
   313         server.Close();
       
   314         }
       
   315         
       
   316     IPTVLOGSTRING_LOW_LEVEL("CreateServerProcess() exit");
       
   317     return  result;
       
   318     }
       
   319 
       
   320 // End of File