19 @file |
19 @file |
20 @internalTechnology |
20 @internalTechnology |
21 */ |
21 */ |
22 |
22 |
23 #include <e32base.h> |
23 #include <e32base.h> |
24 #include <e32base_private.h> |
24 |
25 #include "msctypes.h" |
25 #include "msctypes.h" |
26 #include "mscutils.h" |
|
27 #include "shared.h" |
26 #include "shared.h" |
28 #include "msgservice.h" |
27 #include "msgservice.h" |
29 #include "cusbhostmslogicalunit.h" |
28 #include "cusbhostmslogicalunit.h" |
30 #include "cusbhostmsdevice.h" |
29 #include "cusbhostmsdevice.h" |
31 #include "cusbhostmsserver.h" |
|
32 #include "msdebug.h" |
30 #include "msdebug.h" |
|
31 #include "cusbhostmssession.h" |
33 #include "cusbhostmsdevicethread.h" |
32 #include "cusbhostmsdevicethread.h" |
34 #include "cusbhostmssession.h" |
|
35 #include "debug.h" |
33 #include "debug.h" |
36 |
34 |
37 /** |
35 /** |
38 Constructor |
36 Constructor |
39 */ |
37 */ |
132 CActiveScheduler::Install(s); |
130 CActiveScheduler::Install(s); |
133 |
131 |
134 CUsbHostMsDeviceThread* iThread = (CUsbHostMsDeviceThread*)aPtr; |
132 CUsbHostMsDeviceThread* iThread = (CUsbHostMsDeviceThread*)aPtr; |
135 CActiveScheduler::Add(iThread); |
133 CActiveScheduler::Add(iThread); |
136 |
134 |
137 iThread->iStatus = KRequestPending; |
135 iThread->Start(); |
138 iThread->SetActive(); |
|
139 |
136 |
140 RThread::Rendezvous(KErrNone); |
137 RThread::Rendezvous(KErrNone); |
141 |
138 |
142 // |
139 // |
143 // Ready to run |
140 // Ready to run |
165 |
162 |
166 |
163 |
167 void CUsbHostMsDeviceThread::RunL() |
164 void CUsbHostMsDeviceThread::RunL() |
168 { |
165 { |
169 __MSFNLOG |
166 __MSFNLOG |
170 Lock(); |
167 |
171 if (!iUsbHostMsDevice || iUsbHostMsDevice->IsActive()) |
168 // called on completion of MessageRequest() or Resume() |
172 { |
169 User::LeaveIfError(iStatus.Int()); |
173 // Note: In the case of suspended/resuming state we do not want to get |
170 |
174 // woken by the session msg handler repeatedly |
171 Lock(); |
175 iIsSignalled = EFalse; |
172 if (iUsbHostMsDevice) |
176 } |
173 { |
177 |
174 if (iUsbHostMsDevice->IsSuspended()) |
178 Unlock(); |
175 { |
179 |
176 // request resume |
180 RMessage2 msg; |
177 Unlock(); |
181 TBool handleMsg = EFalse; |
178 iUsbHostMsDevice->Resume(iStatus); |
182 |
179 SetActive(); |
183 for(;;) |
180 return; |
184 { |
181 } |
185 Lock(); |
182 } |
186 if ((iQueueIndex != iDequeueIndex) || iQueueFull) |
183 |
187 { |
184 // process message queue |
188 if (iUsbHostMsDevice && iUsbHostMsDevice->IsSuspended()) |
185 RMessage2 msg = iRMessage2[iDequeueIndex]; |
189 { |
186 |
190 Unlock(); |
187 iDequeueIndex++; |
191 SetActive(); |
188 |
192 iUsbHostMsDevice->ResumeL(iStatus); |
189 if(iDequeueIndex >= KMaxNumMessage) |
193 return; |
190 iDequeueIndex = 0; |
194 } |
191 if(iQueueFull) |
195 |
192 iQueueFull = EFalse; |
196 msg = iRMessage2[iDequeueIndex]; |
193 |
197 handleMsg = ETrue; |
194 HandleMessage(msg); |
198 iDequeueIndex++; |
195 |
199 |
196 if ((iQueueIndex != iDequeueIndex) || iQueueFull) |
200 if(iDequeueIndex >= KMaxNumMessage) |
197 { |
201 { |
198 // self completion |
202 iDequeueIndex = 0; |
199 TRequestStatus* status = &iStatus; |
203 } |
200 User::RequestComplete(status, KErrNone); |
204 if(iQueueFull) |
201 SetActive(); |
205 { |
202 } |
206 iQueueFull = EFalse; |
203 else |
207 } |
204 { |
208 } |
205 iUsbHostMsSession.MessageRequest(iStatus); |
209 Unlock(); |
206 SetActive(); |
210 if (handleMsg) |
207 } |
211 { |
208 Unlock(); |
212 HandleMessage(msg); |
209 } |
213 handleMsg = EFalse; |
210 |
214 } |
211 |
215 else |
212 void CUsbHostMsDeviceThread::DoCancel() |
216 { |
213 { |
217 break; |
214 TRequestStatus* status = &iStatus; |
218 } |
215 User::RequestComplete(status, KErrCancel); |
219 } |
216 } |
220 iStatus = KRequestPending; |
217 |
221 SetActive(); |
218 |
222 } |
219 TInt CUsbHostMsDeviceThread::RunError(TInt aError) |
|
220 { |
|
221 __HOSTPRINT1(_L(">> HOST RunError returning %d"), aError); |
|
222 return KErrNone; |
|
223 } |
223 |
224 |
224 |
225 |
225 TInt CUsbHostMsDeviceThread::QueueMsg(const RMessage2& aMsg) |
226 TInt CUsbHostMsDeviceThread::QueueMsg(const RMessage2& aMsg) |
226 { |
227 { |
227 __MSFNLOG |
228 __MSFNLOG |
|
229 |
228 if (iQueueFull) |
230 if (iQueueFull) |
229 { |
231 { |
230 return KErrOverflow; |
232 return KErrOverflow; |
231 } |
233 } |
232 |
234 |
233 Lock(); |
235 Lock(); |
|
236 |
234 iRMessage2[iQueueIndex] = aMsg; |
237 iRMessage2[iQueueIndex] = aMsg; |
235 iQueueIndex++; |
238 iQueueIndex++; |
236 |
239 |
237 if (iQueueIndex >= KMaxNumMessage) |
240 if (iQueueIndex >= KMaxNumMessage) |
238 { |
241 { |
246 Unlock(); |
249 Unlock(); |
247 return KErrNone; |
250 return KErrNone; |
248 } |
251 } |
249 |
252 |
250 |
253 |
251 void CUsbHostMsDeviceThread::Lock() |
254 CUsbHostMsDeviceThread::CUsbHostMsDeviceThread(CUsbHostMsSession& aUsbHostMsSession, TUint aToken) |
252 { |
|
253 __MSFNLOG |
|
254 iMutex.Wait(); |
|
255 } |
|
256 |
|
257 |
|
258 void CUsbHostMsDeviceThread::Unlock() |
|
259 { |
|
260 __MSFNLOG |
|
261 iMutex.Signal(); |
|
262 } |
|
263 |
|
264 |
|
265 CUsbHostMsDeviceThread::CUsbHostMsDeviceThread(TUint token) |
|
266 : CActive(EPriorityStandard), |
255 : CActive(EPriorityStandard), |
267 iIsSignalled(EFalse), |
256 iUsbHostMsSession(aUsbHostMsSession), |
268 iQueueFull(EFalse) |
257 iQueueFull(EFalse) |
269 { |
258 { |
270 TName nameBuf; |
259 __MSFNLOG |
271 nameBuf.Format(_L("Host Ms ThreadMutex%d"), token); |
260 TBuf<30> nameBuf; |
|
261 nameBuf.Format(_L("Host Ms ThreadMutex%d"), aToken); |
272 iMutex.CreateGlobal(nameBuf,EOwnerProcess); |
262 iMutex.CreateGlobal(nameBuf,EOwnerProcess); |
273 } |
263 } |
274 |
264 |
275 CUsbHostMsDeviceThread::~CUsbHostMsDeviceThread() |
265 CUsbHostMsDeviceThread::~CUsbHostMsDeviceThread() |
276 { |
266 { |
|
267 __MSFNLOG |
|
268 Cancel(); |
277 iMutex.Close(); |
269 iMutex.Close(); |
278 } |
270 } |
279 |
271 |
280 CUsbHostMsDeviceThread* CUsbHostMsDeviceThread::NewL(TUint aToken) |
272 CUsbHostMsDeviceThread* CUsbHostMsDeviceThread::NewL(CUsbHostMsSession& aUsbHostMsSession, TUint aToken) |
281 { |
273 { |
282 CUsbHostMsDeviceThread* r = new (ELeave) CUsbHostMsDeviceThread(aToken); |
274 __MSFNSLOG |
283 CleanupStack::PushL(r); |
275 CUsbHostMsDeviceThread* r = new (ELeave) CUsbHostMsDeviceThread(aUsbHostMsSession, aToken); |
284 CleanupStack::Pop(); |
|
285 return r; |
276 return r; |
286 } |
277 } |
|
278 |
|
279 |
|
280 void CUsbHostMsDeviceThread::Start() |
|
281 { |
|
282 iUsbHostMsSession.MessageRequest(iStatus); |
|
283 SetActive(); |
|
284 } |
287 |
285 |
288 |
286 |
289 /** |
287 /** |
290 Handles the request (in the form of a message) received from the client |
288 Handles the request (in the form of a message) received from the client |
291 @param aMessage The received message |
289 @param aMessage The received message |
321 case EUsbHostMsShutdown: |
319 case EUsbHostMsShutdown: |
322 ret = Shutdown(); |
320 ret = Shutdown(); |
323 break; |
321 break; |
324 default: |
322 default: |
325 // Try Device Handler and Logical Unit Handler |
323 // Try Device Handler and Logical Unit Handler |
|
324 __ASSERT_DEBUG(iUsbHostMsDevice, User::Invariant()); |
326 TDeviceHandler deviceHandler(*iUsbHostMsDevice); |
325 TDeviceHandler deviceHandler(*iUsbHostMsDevice); |
327 TRAP(ret, deviceHandler.HandleMessageL(aMessage)); |
326 TRAP(ret, deviceHandler.HandleMessageL(aMessage)); |
328 break; |
327 break; |
329 } |
328 } |
330 __HOSTPRINT1(_L(">> HOST returning %d"), ret); |
329 __HOSTPRINT1(_L(">> HOST returning %d"), ret); |
|
330 |
331 if (aMessage.Function() != EUsbHostMsNotifyChange) |
331 if (aMessage.Function() != EUsbHostMsNotifyChange) |
332 { |
332 { |
333 aMessage.Complete(ret); |
333 aMessage.Complete(ret); |
334 } |
334 } |
335 } |
335 } |