mmserv/sts/stsimplementation/src/rstssession.cpp
changeset 22 128eb6a32b84
parent 16 43d09473c595
child 31 8dfd592727cb
equal deleted inserted replaced
16:43d09473c595 22:128eb6a32b84
     1 /*
       
     2  * Copyright (c) 2010 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 "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  * The file provides the implementation of the client side session
       
    16  * to the STS Server.
       
    17  */
       
    18 
       
    19 #include "rstssession.h"
       
    20 #include "stsclientservercommon.h"
       
    21 
       
    22 const TUint KNumSlots = 30;
       
    23 
       
    24 /*static*/TInt RStsSession::CallBackThreadMain(TAny* aSession)
       
    25     {
       
    26     TInt err = KErrNoMemory;
       
    27 
       
    28     RThread myThread;
       
    29     myThread.SetPriority(EPriorityAbsoluteHigh);
       
    30     myThread.Close();
       
    31 
       
    32     CTrapCleanup* cleanup = CTrapCleanup::New();
       
    33 
       
    34     if (cleanup)
       
    35         {
       
    36         // Run the server and request a thread rendezvous.
       
    37         TRAP( err, ((RStsSession*)aSession)->RunThreadL() );
       
    38         delete cleanup;
       
    39         }
       
    40 
       
    41     return err;
       
    42     }
       
    43 
       
    44 void RStsSession::RunThreadL()
       
    45     {
       
    46     // Initialisation complete, now signal the client, if requested.
       
    47     RThread::Rendezvous(KErrNone);
       
    48 
       
    49     while (true)
       
    50         {
       
    51         TStsCallBack message;
       
    52         iMsgQueue.ReceiveBlocking(message);
       
    53         TStsCallBackType type = message.callBackType;
       
    54         if (type == EStsPlayAlarmComplete)
       
    55             {
       
    56             message.observer->PlayAlarmComplete(message.alarmContext);
       
    57             }
       
    58         else if (type == EStsShutdown)
       
    59             {
       
    60             break;
       
    61             }
       
    62         else
       
    63             {
       
    64             //TODO: Log error message
       
    65             }
       
    66         }
       
    67     }
       
    68 
       
    69 TInt RStsSession::StartMsgQueue()
       
    70     {
       
    71     // Create a nameless global message queue, then pass the handle to the queue to the server.
       
    72     TInt err = iMsgQueue.CreateGlobal(KNullDesC, 30);
       
    73     if (err == KErrNone)
       
    74         {
       
    75         err = SendReceive(StsMsg_RegisterMsgQueue, TIpcArgs(iMsgQueue));
       
    76         }
       
    77     return err;
       
    78     }
       
    79 
       
    80 TInt RStsSession::StartServer()
       
    81     {
       
    82     TInt err = KErrNone;
       
    83 
       
    84     // Launch the server executable (i.e. in it its own process).
       
    85 
       
    86     // Create a new server process. Simultaneous launching of two such processes 
       
    87     // should be detected when the second one attempts to create the server 
       
    88     // object, failing with KErrAlreadyExists.
       
    89     RProcess server;
       
    90     err = server.Create(KStsServerFile, KNullDesC);
       
    91 
       
    92     if (err == KErrNone)
       
    93         {
       
    94         TRequestStatus rendezvousStatus;
       
    95         server.Rendezvous(rendezvousStatus);
       
    96         server.Resume();
       
    97 
       
    98         // wait for start or death
       
    99         User::WaitForRequest(rendezvousStatus);
       
   100 
       
   101         // we can't use the 'exit reason' if the server panicked as this
       
   102         // is the panic 'reason' and may be '0' which cannot be distinguished
       
   103         // from KErrNone  
       
   104         if (server.ExitType() == EExitPanic)
       
   105             {
       
   106             err = KErrGeneral;
       
   107             }
       
   108         else
       
   109             {
       
   110             err = rendezvousStatus.Int();
       
   111             }
       
   112         }
       
   113 
       
   114     server.Close();
       
   115 
       
   116     return err;
       
   117     }
       
   118 
       
   119 TInt RStsSession::StartThread()
       
   120     {
       
   121     TInt result = iThread.Create(KNullDesC,
       
   122             RStsSession::CallBackThreadMain, KDefaultStackSize,
       
   123             &User::Heap(), (TAny*) this);
       
   124 
       
   125     if (result == KErrNone)
       
   126         {
       
   127         TRequestStatus rendezvousStatus = KRequestPending;
       
   128 
       
   129         //  Register for rendezvous notification when thread is started.
       
   130         iThread.Rendezvous(rendezvousStatus);
       
   131 
       
   132         // Start the thread execution
       
   133         iThread.Resume();
       
   134 
       
   135         // Wait for thread to start.
       
   136         User::WaitForRequest(rendezvousStatus);
       
   137 
       
   138         result = rendezvousStatus.Int();
       
   139 
       
   140         if (result != KErrNone)
       
   141             {
       
   142             iThread.Kill(result);
       
   143             }
       
   144         }
       
   145 
       
   146     return result;
       
   147     }
       
   148 
       
   149 TInt RStsSession::Connect()
       
   150     {
       
   151     // Try to create a session with the server
       
   152     TInt result = CreateSession(KStsServerName, TVersion(
       
   153             KStsServerMajorVersion, KStsServerMinorVersion, KStsServerBuild),
       
   154             KNumSlots, EIpcSession_Sharable);
       
   155 
       
   156     // If the server wasn't found, start the server and try creating a session again
       
   157     if (result == KErrNotFound)
       
   158         {
       
   159         result = StartServer();
       
   160         if (result == KErrNone || result == KErrAlreadyExists)
       
   161             {
       
   162             result = CreateSession(KStsServerName, TVersion(
       
   163                     KStsServerMajorVersion, KStsServerMinorVersion,
       
   164                     KStsServerBuild), KNumSlots, EIpcSession_Sharable);
       
   165             }
       
   166         }
       
   167 
       
   168     // Create thread for receiving asynch callbacks from the server
       
   169     if (result == KErrNone)
       
   170         {
       
   171         result = StartMsgQueue();
       
   172         if (result == KErrNone)
       
   173             {
       
   174             result = StartThread();
       
   175             }
       
   176         }
       
   177 
       
   178     return result;
       
   179     }
       
   180 
       
   181 void RStsSession::Close()
       
   182     {
       
   183     TRequestStatus logonStatus = KRequestPending;
       
   184     iThread.Logon(logonStatus);
       
   185     RSessionBase::Close();
       
   186     User::WaitForRequest(logonStatus);
       
   187     iThread.Close();
       
   188     iMsgQueue.Close();
       
   189     }
       
   190 
       
   191 TInt RStsSession::SendPlayTone(CSystemToneService::TToneType aTone)
       
   192     {
       
   193     return SendReceive(StsMsg_PlayTone, TIpcArgs(aTone));
       
   194     }
       
   195 
       
   196 TInt RStsSession::SendPlayAlarm(CSystemToneService::TAlarmType aAlarm,
       
   197         unsigned int& aAlarmContext, MStsPlayAlarmObserver& aObserver)
       
   198     {
       
   199     TPckg<unsigned int> alarmContextPckg(aAlarmContext);
       
   200     return SendReceive(StsMsg_PlayAlarm, TIpcArgs(aAlarm, &alarmContextPckg,
       
   201             &aObserver));
       
   202     }
       
   203 
       
   204 TInt RStsSession::SendStopAlarm(unsigned int aAlarmContext)
       
   205     {
       
   206     return SendReceive(StsMsg_StopAlarm, TIpcArgs(aAlarmContext));
       
   207     }