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 } |