mmserv/sts/stsimplementation/src/rstssession.cpp
changeset 16 43d09473c595
parent 14 80975da52420
equal deleted inserted replaced
14:80975da52420 16:43d09473c595
    19 #include "rstssession.h"
    19 #include "rstssession.h"
    20 #include "stsclientservercommon.h"
    20 #include "stsclientservercommon.h"
    21 
    21 
    22 const TUint KNumSlots = 30;
    22 const TUint KNumSlots = 30;
    23 
    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 
    24 TInt RStsSession::StartServer()
    80 TInt RStsSession::StartServer()
    25     {
    81     {
    26     TInt err = KErrNone;
    82     TInt err = KErrNone;
    27 
    83 
    28     // Launch the server executable (i.e. in it its own process).
    84     // Launch the server executable (i.e. in it its own process).
    35 
    91 
    36     if (err == KErrNone)
    92     if (err == KErrNone)
    37         {
    93         {
    38         TRequestStatus rendezvousStatus;
    94         TRequestStatus rendezvousStatus;
    39         server.Rendezvous(rendezvousStatus);
    95         server.Rendezvous(rendezvousStatus);
    40 
    96         server.Resume();
    41         if (rendezvousStatus != KRequestPending)
    97 
    42             {
    98         // wait for start or death
    43             server.Kill(0); // abort startup
    99         User::WaitForRequest(rendezvousStatus);
    44             }
       
    45         else
       
    46             {
       
    47             server.Resume(); // logon OK - start the server thread
       
    48             } // end if
       
    49 
       
    50         User::WaitForRequest(rendezvousStatus); // wait for start or death
       
    51 
   100 
    52         // we can't use the 'exit reason' if the server panicked as this
   101         // we can't use the 'exit reason' if the server panicked as this
    53         // is the panic 'reason' and may be '0' which cannot be distinguished
   102         // is the panic 'reason' and may be '0' which cannot be distinguished
    54         // from KErrNone  
   103         // from KErrNone  
    55         err = (server.ExitType() == EExitPanic)
   104         if (server.ExitType() == EExitPanic)
    56                                                 ? KErrGeneral
   105             {
    57                                                    : rendezvousStatus.Int();
   106             err = KErrGeneral;
    58         server.Close();
   107             }
    59         }
   108         else
       
   109             {
       
   110             err = rendezvousStatus.Int();
       
   111             }
       
   112         }
       
   113 
       
   114     server.Close();
    60 
   115 
    61     return err;
   116     return err;
    62     }
   117     }
    63 
   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 
    64 TInt RStsSession::Connect()
   149 TInt RStsSession::Connect()
    65     {
   150     {
       
   151     // Try to create a session with the server
    66     TInt result = CreateSession(KStsServerName, TVersion(
   152     TInt result = CreateSession(KStsServerName, TVersion(
    67             KStsServerMajorVersion, KStsServerMinorVersion, KStsServerBuild),
   153             KStsServerMajorVersion, KStsServerMinorVersion, KStsServerBuild),
    68             KNumSlots, EIpcSession_Sharable);
   154             KNumSlots, EIpcSession_Sharable);
    69 
   155 
       
   156     // If the server wasn't found, start the server and try creating a session again
    70     if (result == KErrNotFound)
   157     if (result == KErrNotFound)
    71         {
   158         {
    72         result = StartServer();
   159         result = StartServer();
    73         if (result == KErrNone || result == KErrAlreadyExists)
   160         if (result == KErrNone || result == KErrAlreadyExists)
    74             {
   161             {
    75             result = CreateSession(KStsServerName, TVersion(
   162             result = CreateSession(KStsServerName, TVersion(
    76                     KStsServerMajorVersion, KStsServerMinorVersion,
   163                     KStsServerMajorVersion, KStsServerMinorVersion,
    77                     KStsServerBuild), KNumSlots);
   164                     KStsServerBuild), KNumSlots, EIpcSession_Sharable);
    78             }
   165             }
    79         }
   166         }
    80 
   167 
       
   168     // Create thread for receiving asynch callbacks from the server
    81     if (result == KErrNone)
   169     if (result == KErrNone)
    82         {
   170         {
    83         result = ShareAuto();
   171         result = StartMsgQueue();
    84 
   172         if (result == KErrNone)
    85         if (result != KErrNone)
   173             {
    86             {
   174             result = StartThread();
    87             Close();
       
    88             }
   175             }
    89         }
   176         }
    90 
   177 
    91     return result;
   178     return result;
    92     }
   179     }
    93 
   180 
    94 void RStsSession::Close()
   181 void RStsSession::Close()
    95     {
   182     {
       
   183     TRequestStatus logonStatus = KRequestPending;
       
   184     iThread.Logon(logonStatus);
    96     RSessionBase::Close();
   185     RSessionBase::Close();
    97     }
   186     User::WaitForRequest(logonStatus);
    98 
   187     iThread.Close();
    99 TInt RStsSession::SendPlayTone(CSystemToneService::TToneType aToneType,
   188     iMsgQueue.Close();
   100         unsigned int& aPlayToneContext)
   189     }
   101     {
   190 
   102     TPckg<unsigned int> playToneContextPckg(aPlayToneContext);
   191 TInt RStsSession::SendPlayTone(CSystemToneService::TToneType aTone)
   103     return SendReceive(StsMsg_PlayTone, TIpcArgs((TInt) aToneType,
   192     {
   104             &playToneContextPckg));
   193     return SendReceive(StsMsg_PlayTone, TIpcArgs(aTone));
   105     }
   194     }
   106 
   195 
   107 TInt RStsSession::SendStopTone(unsigned int aPlayToneContext)
   196 TInt RStsSession::SendPlayAlarm(CSystemToneService::TAlarmType aAlarm,
   108     {
   197         unsigned int& aAlarmContext, MStsPlayAlarmObserver& aObserver)
   109     return SendReceive(StsMsg_StopTone, TIpcArgs(aPlayToneContext));
   198     {
   110     }
   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     }