|
1 /* |
|
2 * Copyright (c) 2009 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 #include <kern_priv.h> // For DMutex |
|
21 #include "p2puserchannel.h" // For DP2PUserChannel |
|
22 #include "msgqueue.h" // For DMsgQueue |
|
23 #include "p2proutertrace.h" // For C_TRACE, ASSERT_RESET.. and fault codes. |
|
24 #include "memapi.h" // MemApi |
|
25 #include "p2pdefs.h" // For EP2PAmountOfProtocols |
|
26 |
|
27 enum TP2PUserChannelFaults |
|
28 { |
|
29 EP2PUserChannelMemAllocFail = 0x00, |
|
30 EP2PUserChannelMemAllocFail1, |
|
31 EP2PUserChannelMemAllocFail2, |
|
32 EP2PUserChannelWrongRequest, |
|
33 EP2PUserChannelWrongRequest1, |
|
34 EP2PUserChannelWrongRequest2, |
|
35 EP2PUserChannelWrongRequest3, |
|
36 EP2PUserChannelWrongRequest4, |
|
37 EP2PUserChannelWrongRequest5, |
|
38 EP2PUserChannelWrongRequest6, |
|
39 EP2PUserChannelWrongRequest7, |
|
40 EP2PUserChannelWrongParam, |
|
41 EP2PUserChannelWrongParam2, |
|
42 EP2PUserChannelProtocolIdNotSpecified, |
|
43 EP2PUserChannelOverTheArrayLimits, |
|
44 EP2PUserChannelDesWriteFailed, |
|
45 EP2PUserChannelSameRequest, |
|
46 EP2PUserChannelSameRequest2, |
|
47 EP2PUserChannelNullParam, |
|
48 EP2PUserChannelNullParam2, |
|
49 EP2PUserChannelDesReadFailed, |
|
50 EP2PIUserChannelfNotThreadContext, |
|
51 EP2PIUserChannelfNotThreadContext2, |
|
52 EP2PIUserChannelfNotThreadContext3, |
|
53 EP2PIUserChannelfNotThreadContext4, |
|
54 EP2PIUserChannelfNotThreadContext5, |
|
55 EP2PUserChannelMutexCreateFailed, |
|
56 EP2PUserChannelMutexWaitFailed, |
|
57 EP2PUserChannelMutexWaitFailed2, |
|
58 EP2PUserChannelMutexWaitFailed3, |
|
59 EP2PUserChannelMutexWaitFailed4, |
|
60 EP2PUserChannelReqQueueOutOfSync, |
|
61 EP2PUserChannelReqQueueOutOfSync1, |
|
62 EP2PUserChannelReqQueueOutOfSync2, |
|
63 EP2PUserChannelReqQueueOutOfSync3, |
|
64 EP2PUserChannelReqQueueOutOfSync4, |
|
65 EP2PUserChannelReqQueueOutOfSync5, |
|
66 EP2PUserChannelReqQueueOutOfSync6, |
|
67 EP2PUserChannelReqQueueOutOfSync7, |
|
68 EP2PUserChannelReqQueueOverTheLimits, |
|
69 EP2PUserChannelReqQueueOverTheLimits2, |
|
70 EP2PUserChannelReqQueueWrongRequest, |
|
71 EP2PUserChannelReqQueueWrongRequest2, |
|
72 EP2PUserChannelReqQueueMemoryAllocFailure, |
|
73 EP2PUserChannelReqQueueCommon, |
|
74 }; |
|
75 |
|
76 |
|
77 // Extracting and adding the pipeheader. |
|
78 const TInt KFirstParam( 0 ); |
|
79 const TInt KSecondParam( 1 ); |
|
80 const TInt KNoParams( KErrNone ); |
|
81 const TInt KOneParam( 1 ); |
|
82 const TInt KTwoParams( 2 ); |
|
83 const TInt KThreeParams( 3 ); |
|
84 |
|
85 const TInt KDestStartOffset( 0 ); |
|
86 const TInt KP2PLddEmptyRxPriori( 1 ); |
|
87 const TInt KP2PLddCompletePriori( 1 ); |
|
88 |
|
89 const TInt KP2PMaximumSendSize( 0xffff ); |
|
90 |
|
91 //DMutex* DP2PUserChannel::iShP2PProtocolIdMutex = NULL; |
|
92 _LIT8( KP2PUserChannelP2PProtocolIdMutex, "P2PUserChannelP2PProtocolIdMutex" ); |
|
93 |
|
94 // |
|
95 // user<> kernel interaction() done in LDD DFC thread |
|
96 // |
|
97 // kernel<>kernel interaction() done in Extension DFC thread |
|
98 // |
|
99 // DEMAND_PAGING |
|
100 // Receive (write k>u) is done only in LDD thread context to allow Extension thread to continue when dp swaps. |
|
101 // Send ((write u>k) is not done at the moment in LDD thread context only. Check is it possible to happend (not to be in usable memory after send (unlikely?)). |
|
102 DP2PUserChannel::DP2PUserChannel( |
|
103 // None |
|
104 ) |
|
105 : |
|
106 iShP2PProtocolId( EP2PAmountOfProtocols ), |
|
107 iReceiveBufPtr( NULL ), |
|
108 iRx( NULL ), |
|
109 iP2PReqQueue( NULL ), |
|
110 iThread( &Kern::CurrentThread() ) |
|
111 { |
|
112 |
|
113 C_TRACE( ( _T( "DP2PUserChannel::DP2PUserChannel>" ) ) ); |
|
114 iRouterIf = MP2PChRouterIf::GetIf(); |
|
115 ASSERT_RESET_ALWAYS( iRouterIf, ( EP2PUserChannelMemAllocFail | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
116 iEmptyRxQueueDfc = new TDfc( EmptyRxQueueDfc, this, iRouterIf->GetDfcThread( MP2PChRouterIf::EP2PLddDfcThread ), KP2PLddEmptyRxPriori ); |
|
117 iCompleteChannelRequestDfc = new TDfc( CompleteChReqDfc, this, iRouterIf->GetDfcThread( MP2PChRouterIf::EP2PLddDfcThread ), KP2PLddCompletePriori ); |
|
118 iP2PReqQueue = new DP2PReqQueue(); |
|
119 ASSERT_RESET_ALWAYS( iEmptyRxQueueDfc && iCompleteChannelRequestDfc && iP2PReqQueue, ( EP2PUserChannelMemAllocFail1 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
120 TInt err( Kern::MutexCreate( iShP2PProtocolIdMutex, KP2PUserChannelP2PProtocolIdMutex, KMutexOrdGeneral0 ) ); |
|
121 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexCreateFailed | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
122 C_TRACE( ( _T( "DP2PUserChannel::DP2PUserChannel<" ) ) ); |
|
123 |
|
124 } |
|
125 |
|
126 DP2PUserChannel::~DP2PUserChannel( |
|
127 // None |
|
128 ) |
|
129 { |
|
130 |
|
131 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x>" ), this, iShP2PProtocolId ) ); |
|
132 // owned starts |
|
133 if( iEmptyRxQueueDfc ) |
|
134 { |
|
135 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iEmptyRxQueueDfc 0x%x" ), this, iShP2PProtocolId, iEmptyRxQueueDfc ) ); |
|
136 iEmptyRxQueueDfc->Cancel(); |
|
137 delete iEmptyRxQueueDfc; |
|
138 iEmptyRxQueueDfc = NULL; |
|
139 } |
|
140 if( iCompleteChannelRequestDfc ) |
|
141 { |
|
142 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iCompleteChannelRequestDfc 0x%x" ), this, iShP2PProtocolId, iCompleteChannelRequestDfc ) ); |
|
143 iCompleteChannelRequestDfc->Cancel(); |
|
144 delete iCompleteChannelRequestDfc; |
|
145 iCompleteChannelRequestDfc = NULL; |
|
146 } |
|
147 if( iRx ) |
|
148 { |
|
149 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iRx 0x%x" ), this, iShP2PProtocolId, iRx ) ); |
|
150 delete iRx; |
|
151 iRx = NULL; |
|
152 } |
|
153 if( iReceiveBufPtr ) |
|
154 { |
|
155 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iReceiveBufPtr 0x%x" ), this, iShP2PProtocolId, iReceiveBufPtr ) ); |
|
156 iReceiveBufPtr = NULL; |
|
157 } |
|
158 if( iP2PReqQueue ) |
|
159 { |
|
160 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iP2PReqQueue 0x%x" ), this, iShP2PProtocolId, iP2PReqQueue ) ); |
|
161 delete iP2PReqQueue; |
|
162 iP2PReqQueue = NULL; |
|
163 } |
|
164 // No need to check, if failed reseted already |
|
165 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iShP2PProtocolIdMutex 0x%x" ), this, iShP2PProtocolId, iShP2PProtocolIdMutex ) ); |
|
166 iShP2PProtocolIdMutex->Close( NULL ); |
|
167 // owned ends |
|
168 iRouterIf = NULL; |
|
169 Kern::SafeClose( reinterpret_cast<DObject*&>(iThread), NULL ); |
|
170 C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x<" ), this, iShP2PProtocolId ) ); |
|
171 |
|
172 } |
|
173 |
|
174 /* |
|
175 * Executed in user thread context thread inside CS, cannot be pre-empted. |
|
176 * Channel can not be used before creation, so no need to synch if congesting only btw the creating user thread and one thread. |
|
177 */ |
|
178 TInt DP2PUserChannel::DoCreate( |
|
179 TInt, //aUnit, // No need to use this, we can avoid the limit of 32 channels |
|
180 const TDesC8* anInfo, // Contains the protocolId |
|
181 const TVersion& // aVer // Not used at the moment. |
|
182 ) |
|
183 { |
|
184 |
|
185 C_TRACE( ( _T( "DP2PUserChannel::DoCreate 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, anInfo ) ); |
|
186 if( !Kern::CurrentThreadHasCapability( ECapabilityCommDD, __PLATSEC_DIAGNOSTIC_STRING( "Check by: P2PRouter" ) ) ) return KErrPermissionDenied; |
|
187 TRACE_ASSERT_INFO( anInfo, EP2PUserChannelProtocolIdNotSpecified ); |
|
188 // Check for channel number inside anInfo. |
|
189 TRACE_ASSERT_INFO( anInfo->Length() > 0, ( EP2PUserChannelOverTheArrayLimits | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
190 if( !anInfo || anInfo->Length() == 0 ) return KErrNotSupported; |
|
191 TUint8 protocolId = static_cast<TUint8>( ( *anInfo )[ 0 ] ); |
|
192 TRACE_ASSERT_INFO( ( protocolId < EP2PAmountOfProtocols ), ( EP2PUserChannelWrongParam | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
193 if( protocolId >= EP2PAmountOfProtocols ) return KErrNotSupported; |
|
194 TInt err( Kern::MutexWait( *iShP2PProtocolIdMutex ) ); |
|
195 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
196 // If channel is already used for some protocol. |
|
197 if( iShP2PProtocolId != EP2PAmountOfProtocols ) |
|
198 { |
|
199 Kern::MutexSignal( *iShP2PProtocolIdMutex ); |
|
200 return KErrAlreadyExists; |
|
201 } |
|
202 iShP2PProtocolId = ~protocolId; |
|
203 Kern::MutexSignal( *iShP2PProtocolIdMutex ); |
|
204 C_TRACE( ( _T( "DP2PUserChannel::DoCreate protocolId 0x%x 0x%x" ), this, iShP2PProtocolId ) ); |
|
205 iRx = new DMsgQueue( KP2PLddRxQueuSize ); |
|
206 ASSERT_RESET_ALWAYS( iRx, ( EP2PUserChannelMemAllocFail2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
207 // Other DFC functions handling user<>kernel copying done in ldd DFC. Ldd DFC function priority is 1. |
|
208 SetDfcQ( iRouterIf->GetDfcThread( MP2PChRouterIf::EP2PDfcThread ) ); |
|
209 iMsgQ.Receive(); |
|
210 DObject* thread = reinterpret_cast<DObject*>( iThread ); |
|
211 // Open is needed to increase ref count to calling thread that is decreased in Kern::SafeClose |
|
212 // Possible returns KErrNone ? KErrGeneral |
|
213 TInt threadOpen( thread->Open() ); |
|
214 TRACE_ASSERT_INFO( threadOpen == KErrNone, (TUint8)iShP2PProtocolId ); |
|
215 C_TRACE( ( _T( "DP2PUserChannel::DoCreate 0x%x 0x%x %d<" ), this, iShP2PProtocolId, threadOpen ) ); |
|
216 return threadOpen; |
|
217 |
|
218 } |
|
219 |
|
220 void DP2PUserChannel::HandleMsg( |
|
221 TMessageBase* aMsg |
|
222 ) |
|
223 { |
|
224 |
|
225 C_TRACE( ( _T( "DP2PUserChannel::HandleMsg 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, aMsg ) ); |
|
226 TThreadMessage& m= *( static_cast< TThreadMessage* >( aMsg ) ); |
|
227 TInt id( m.iValue ); |
|
228 if( static_cast<TInt>( ECloseMsg ) == id ) |
|
229 { |
|
230 C_TRACE( ( _T( "DP2PUserChannel::HandleMsg ECloseMsg 0x%x 0x%x 0x%x" ), this, iShP2PProtocolId, aMsg ) ); |
|
231 m.Complete( HandleSyncRequest( EP2PClose, NULL ), EFalse ); |
|
232 } |
|
233 else if( KMaxTInt == id ) |
|
234 { |
|
235 C_TRACE( ( _T( "DP2PUserChannel::HandleMsg cancel 0x%x 0x%x 0x%x" ), this, iShP2PProtocolId, aMsg ) ); |
|
236 DoCancel( id, m.Int0() ); |
|
237 m.Complete( KErrNone, ETrue ); |
|
238 } |
|
239 else |
|
240 { |
|
241 ASSERT_RESET_ALWAYS( ( KErrNotFound < id ), ( EP2PUserChannelWrongRequest | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
242 C_TRACE( ( _T( "DP2PUserChannel::HandleMsg request 0x%x 0x%x %d 0x%x" ), this, iShP2PProtocolId, id, aMsg ) ); |
|
243 TInt completeValue( KErrNone ); |
|
244 TInt ulen( KErrNotFound ); |
|
245 switch ( id ) |
|
246 { |
|
247 case EP2PClose: |
|
248 { |
|
249 ulen = KNoParams; |
|
250 break; |
|
251 } |
|
252 case EP2PSend: |
|
253 case EP2PAsyncConnectionLost: |
|
254 { |
|
255 ulen = KOneParam; |
|
256 break; |
|
257 } |
|
258 case EP2PAsyncOpen: |
|
259 case EP2PAsyncReceive: |
|
260 { |
|
261 ulen = KTwoParams; |
|
262 break; |
|
263 } |
|
264 default: |
|
265 { |
|
266 ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest1 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
267 break; |
|
268 } |
|
269 } |
|
270 TUint32* table[ KThreeParams ]; |
|
271 completeValue = Kern::ThreadRawRead( iThread, m.Ptr0(), table, ulen * sizeof( TAny* ) ); |
|
272 if( completeValue == KErrNone ) |
|
273 { |
|
274 switch( id ) |
|
275 { |
|
276 // All asynchronous requests. |
|
277 case EP2PAsyncOpen: |
|
278 case EP2PAsyncReceive: |
|
279 case EP2PAsyncConnectionLost: |
|
280 { |
|
281 // No need to check return value in async functions, completed to user |
|
282 HandleAsyncRequest( id, table ); |
|
283 break; |
|
284 } |
|
285 case EP2PClose: |
|
286 case EP2PSend: |
|
287 { |
|
288 completeValue = HandleSyncRequest( id, table ); |
|
289 break; |
|
290 } |
|
291 default: |
|
292 { |
|
293 ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
294 break; |
|
295 } |
|
296 } |
|
297 } |
|
298 m.Complete( completeValue, ETrue ); |
|
299 } |
|
300 C_TRACE( ( _T( "DP2PUserChannel::HandleMsg 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId, aMsg ) ); |
|
301 |
|
302 } |
|
303 |
|
304 TInt DP2PUserChannel::Request( |
|
305 TInt aReqNo, |
|
306 TAny* a1, |
|
307 TAny* //a2 |
|
308 ) |
|
309 { |
|
310 |
|
311 C_TRACE( ( _T( "DP2PUserChannel::Request 0x%x 0x%x %d 0x%x>" ), this, iShP2PProtocolId, aReqNo, a1 ) ); |
|
312 // Programmer errors. |
|
313 ASSERT_RESET_ALWAYS( aReqNo >= ( TInt ) EMinRequestId, ( EP2PUserChannelWrongRequest3 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
314 ASSERT_RESET_ALWAYS( ( aReqNo <= EP2PLastAsyncRequest || aReqNo == KMaxTInt ), ( EP2PUserChannelWrongRequest4 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
315 // Wrong API usage e.g. called function when interface is not open so panic the client thread. |
|
316 ASSERT_PANIC_USER_THREAD_ALWAYS( ( iShP2PProtocolId < EP2PAmountOfProtocols || EP2PAsyncOpen == aReqNo ), iThread, ( EP2PUserChannelWrongParam2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
317 TInt result( KErrNotFound ); |
|
318 // All request go in kernel context and with ::DoControl call. |
|
319 TThreadMessage& m=Kern::Message(); |
|
320 m.iValue = aReqNo; |
|
321 m.iArg[ KFirstParam ] = a1; |
|
322 m.iArg[ KSecondParam ] = NULL; |
|
323 result = m.SendReceive( &iMsgQ ); |
|
324 C_TRACE( ( _T( "DP2PUserChannel::Request 0x%x 0x%x %d 0x%x %d<" ), this, iShP2PProtocolId, aReqNo, a1, result ) ); |
|
325 return result; |
|
326 |
|
327 } |
|
328 |
|
329 ///// Functions from MChannelCallback start (from extension binary) |
|
330 // called in router ext context |
|
331 void DP2PUserChannel::ConnectionLost() |
|
332 { |
|
333 |
|
334 C_TRACE( ( _T( "DP2PKernelChannel::ConnectionLost 0x%x 0x%x %d %d 0x%x>" ), this, iShP2PProtocolId ) ); |
|
335 EnqueChannelRequestCompleteDfc( EP2PAsyncConnectionLost, KErrNotReady ); |
|
336 ResetQueues(); |
|
337 //Closing(); |
|
338 C_TRACE( ( _T( "DP2PKernelChannel::ConnectionLost 0x%x 0x%x %d %d 0x%x<" ), this, iShP2PProtocolId ) ); |
|
339 |
|
340 } |
|
341 |
|
342 // called in router ext context |
|
343 void DP2PUserChannel::EnqueChannelRequestCompleteDfc( |
|
344 TInt aRequest, |
|
345 TInt aStatusToComplete |
|
346 ) |
|
347 { |
|
348 |
|
349 C_TRACE( ( _T( "DP2PUserChannel::EnqueChannelRequestCompleteDfc 0x%x 0x%x %d %d>" ), this, iShP2PProtocolId, aRequest, aStatusToComplete ) ); |
|
350 ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
351 TP2PReq req( static_cast<TP2PAsyncRequest>( aRequest ), aStatusToComplete ); |
|
352 if( iP2PReqQueue->Add( req ) ) |
|
353 { |
|
354 TRACE_ASSERT_INFO( !iCompleteChannelRequestDfc->Queued(), (TUint8)iShP2PProtocolId << KProtocolIdShift | (TUint16)aRequest ); |
|
355 iCompleteChannelRequestDfc->Enque(); |
|
356 } |
|
357 C_TRACE( ( _T( "DP2PUserChannel::EnqueChannelRequestCompleteDfc 0x%x 0x%x %d %d<" ), this, iShP2PProtocolId, aRequest, aStatusToComplete ) ); |
|
358 |
|
359 } |
|
360 |
|
361 // This is called in 1...N thread contextes |
|
362 void DP2PUserChannel::ReceiveMsg( |
|
363 const TDesC8& aMessage |
|
364 ) |
|
365 { |
|
366 |
|
367 C_TRACE( ( _T( "DP2PUserChannel::ReceiveMsg 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, &aMessage ) ); |
|
368 // Can only be called from thread context. |
|
369 ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext3 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
370 iRx->Add( aMessage ); |
|
371 iEmptyRxQueueDfc->Enque(); |
|
372 C_TRACE( ( _T( "DP2PUserChannel::ReceiveMsg 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId, &aMessage ) ); |
|
373 |
|
374 } |
|
375 |
|
376 |
|
377 ///// Functions from MChannelCallback end (from extension binary) |
|
378 |
|
379 // Run in P2P extension kernel thread context. |
|
380 void DP2PUserChannel::Close( |
|
381 const TUint8 aP2PProtocolId |
|
382 ) |
|
383 { |
|
384 |
|
385 C_TRACE( ( _T( "DP2PUserChannel::Close 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, aP2PProtocolId ) ); |
|
386 if( EP2PAmountOfProtocols != iShP2PProtocolId ) |
|
387 { |
|
388 C_TRACE( ( _T( "DP2PKernelChannel::Close closing 0x%x 0x%x>" ), iShP2PProtocolId, aP2PProtocolId ) ); |
|
389 iRouterIf->Close( aP2PProtocolId ); |
|
390 } |
|
391 iShP2PProtocolId = EP2PAmountOfProtocols; |
|
392 C_TRACE( ( _T( "DP2PUserChannel::Close 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId, aP2PProtocolId ) ); |
|
393 |
|
394 } |
|
395 |
|
396 void DP2PUserChannel::Closing( |
|
397 // None |
|
398 ) |
|
399 { |
|
400 |
|
401 C_TRACE( ( _T( "DP2PUserChannel::Closing 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId ) ); |
|
402 ResetQueues(); |
|
403 TInt err( Kern::MutexWait( *iShP2PProtocolIdMutex ) ); |
|
404 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
405 if( EP2PAmountOfProtocols != iShP2PProtocolId ) |
|
406 { |
|
407 // Cancel any outstanding request. // remember in asynch close not to close it asynhronously |
|
408 for( TInt i( 0 ); i < EP2PLastAsyncRequest; ++i ) |
|
409 { |
|
410 if( iP2PReqQueue->GetReq( static_cast< TP2PAsyncRequest >( i ) ) ) |
|
411 { |
|
412 C_TRACE( ( _T( "DP2PUserChannel::Closing 0x%x 0x%x EP2PClose req to cancel" ), this, iShP2PProtocolId, i ) ); |
|
413 DoCancel( KMaxTInt, i ); |
|
414 } |
|
415 } |
|
416 Close( iShP2PProtocolId ); |
|
417 } |
|
418 Kern::MutexSignal( *iShP2PProtocolIdMutex ); |
|
419 C_TRACE( ( _T( "DP2PUserChannel::Closing 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId ) ); |
|
420 |
|
421 } |
|
422 |
|
423 // Run in P2P user channel kernel thread context. |
|
424 void DP2PUserChannel::CompleteChReqDfc( |
|
425 TAny* aPtr |
|
426 ) |
|
427 { |
|
428 |
|
429 C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc>" ) ) ); |
|
430 // Make sure that user side is accessed only by ldd DFCThread. |
|
431 ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
432 //TODO ASSERT_DFCTHREAD_INLDD(); |
|
433 DP2PUserChannel* chPtr = reinterpret_cast<DP2PUserChannel*>( aPtr ); |
|
434 C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x" ), chPtr, chPtr->iShP2PProtocolId ) ); |
|
435 TP2PReq requ = chPtr->iP2PReqQueue->Get(); |
|
436 if( EP2PAsyncOpen == requ.iRequest ) |
|
437 { |
|
438 C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x status %d" ), chPtr, chPtr->iShP2PProtocolId, requ.iCompleteStatus ) ); |
|
439 // Check of KErrNone and KErrInUse (same object same id open) and in only those cases ~iCh = ~~iCh kernel already has. |
|
440 TInt err( Kern::MutexWait( *chPtr->iShP2PProtocolIdMutex ) ); |
|
441 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed3 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
442 TUint8 chNumber( ( KErrNone == requ.iCompleteStatus || KErrInUse == requ.iCompleteStatus ? ~chPtr->iShP2PProtocolId : EP2PAmountOfProtocols ) ); |
|
443 chPtr->iShP2PProtocolId = chNumber; |
|
444 Kern::MutexSignal( *chPtr->iShP2PProtocolIdMutex ); |
|
445 } |
|
446 TRequestStatus* status( chPtr->iP2PReqQueue->GetReq( requ.iRequest ) ); |
|
447 Kern::RequestComplete( chPtr->iThread, status, requ.iCompleteStatus ); |
|
448 C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x req %d status %d" ), chPtr, chPtr->iShP2PProtocolId, requ.iRequest, requ.iCompleteStatus ) ); |
|
449 chPtr->iP2PReqQueue->SetReq( requ.iRequest, NULL ); |
|
450 if( !chPtr->iP2PReqQueue->Empty() ) |
|
451 { |
|
452 CompleteChReqDfc( chPtr ); |
|
453 } |
|
454 C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x<" ), chPtr, chPtr->iShP2PProtocolId ) ); |
|
455 |
|
456 } |
|
457 |
|
458 void DP2PUserChannel::EmptyRxQueueDfc( |
|
459 TAny* aPtr // Pointer to self |
|
460 ) |
|
461 { |
|
462 |
|
463 // TODO ASSERT_DFCTHREAD_INLDD(); |
|
464 DP2PUserChannel& chTmp = *reinterpret_cast<DP2PUserChannel*>( aPtr ); |
|
465 C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc 0x%x 0x%x>" ), &chTmp, chTmp.iShP2PProtocolId ) ); |
|
466 if( ( chTmp.iP2PReqQueue->GetReq( EP2PAsyncReceive ) ) && ( chTmp.iRx->Count() > 0 ) ) |
|
467 { |
|
468 TDes8& tmpDes = chTmp.iRx->Get(); |
|
469 // Write to user address space (iReceiveBufPtr) the content of tmpDes starting from zero offset as 8bit descriptor data. |
|
470 TInt writeError( Kern::ThreadDesWrite( chTmp.iThread, chTmp.iReceiveBufPtr, tmpDes, KDestStartOffset, KChunkShiftBy0, chTmp.iThread ) ); |
|
471 TRACE_ASSERT_INFO( writeError == KErrNone, ( chTmp.iShP2PProtocolId | writeError << KClassIdentifierShift ) ); |
|
472 C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc writing 0x%x k>u 0x%x 0x%x writeError %d length %d" ), &tmpDes, chTmp.iReceiveBufPtr, chTmp.iShP2PProtocolId, writeError, tmpDes.Length() ) ); |
|
473 TP2PReq req( static_cast<TP2PAsyncRequest>( EP2PAsyncReceive ), writeError ); |
|
474 if( chTmp.iP2PReqQueue->Add( req ) ) |
|
475 { |
|
476 TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() ); |
|
477 CompleteChReqDfc( &chTmp ); |
|
478 } |
|
479 MemApi::DeallocBlock( tmpDes ); |
|
480 } |
|
481 else |
|
482 { |
|
483 C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc 0x%x 0x%x rx inactive or no message" ), &chTmp, chTmp.iShP2PProtocolId ) ); |
|
484 } |
|
485 C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc 0x%x 0x%x<" ), &chTmp, chTmp.iShP2PProtocolId ) ); |
|
486 |
|
487 } |
|
488 |
|
489 |
|
490 void DP2PUserChannel::ResetQueues( |
|
491 // None |
|
492 ) |
|
493 { |
|
494 |
|
495 C_TRACE( ( _T( "DP2PUserChannel::ResetQueues 0x%x 0x%x>" ), this, iShP2PProtocolId ) ); |
|
496 if( iRx ) |
|
497 { |
|
498 C_TRACE( ( _T( "DP2PUserChannel::ResetQueues 0x%x 0x%x iRx 0x%x" ), this, iShP2PProtocolId, iRx ) ); |
|
499 while( iRx->Count() ) |
|
500 { |
|
501 MemApi::DeallocBlock( iRx->Get() ); |
|
502 } |
|
503 } |
|
504 C_TRACE( ( _T( "DP2PUserChannel::ResetQueues 0x%x 0x%x<" ), this, iShP2PProtocolId ) ); |
|
505 |
|
506 } |
|
507 |
|
508 void DP2PUserChannel::HandleAsyncRequest( |
|
509 TInt aRequest, |
|
510 TAny* a1 |
|
511 ) |
|
512 { |
|
513 |
|
514 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x %d>" ), this, iShP2PProtocolId, aRequest ) ); |
|
515 ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext4 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
516 TUint32* tablePtr = reinterpret_cast<TUint32*>( a1 ); |
|
517 TRACE_ASSERT_INFO( tablePtr[ KFirstParam ], (TUint16)aRequest ); |
|
518 TRequestStatus* requestStatus = reinterpret_cast<TRequestStatus*>( tablePtr[ KFirstParam ] ); |
|
519 // If request already active. |
|
520 if( ( iP2PReqQueue->GetReq( static_cast<TP2PAsyncRequest>( aRequest ) ) ) ) |
|
521 { |
|
522 // Fault if request is already pending and the request status pointer is different. |
|
523 // Fault prints 0-7bits: request, 8-15bits: ch number, 16-31bits: fault identifier |
|
524 // Assert cause request already active. |
|
525 TRACE_ASSERT_INFO( 0, ( EP2PUserChannelSameRequest | static_cast<TUint8>( iShP2PProtocolId ) << KProtocolIdShift | static_cast<TUint8>( aRequest ) << KExtraInfoShift ) ); |
|
526 // Active object should not give same request object twice before completing the first one. |
|
527 ASSERT_PANIC_USER_THREAD_ALWAYS( iP2PReqQueue->GetReq( static_cast< TP2PAsyncRequest >( aRequest ) ) == requestStatus, iThread, |
|
528 ( EP2PUserChannelSameRequest2 | static_cast<TUint8>( iShP2PProtocolId ) << KProtocolIdShift | static_cast<TUint8>( aRequest ) << KExtraInfoShift ) ); |
|
529 } |
|
530 else |
|
531 { |
|
532 iP2PReqQueue->SetReq( static_cast<TP2PAsyncRequest>( aRequest ), requestStatus ); |
|
533 switch ( aRequest ) |
|
534 { |
|
535 case EP2PAsyncOpen: |
|
536 { |
|
537 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x EP2PAsyncOpen" ), this, iShP2PProtocolId ) ); |
|
538 // Set open to pending to router, router completes it when the interconnection to other point is ready. |
|
539 iRouterIf->Open( ~iShP2PProtocolId, this ); |
|
540 break; |
|
541 } |
|
542 case EP2PAsyncReceive: |
|
543 { |
|
544 iReceiveBufPtr = reinterpret_cast<TAny*>( tablePtr[ KSecondParam ] ); |
|
545 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x EP2PAsyncReceive 0x%x" ), this, iShP2PProtocolId, iReceiveBufPtr ) ); |
|
546 iEmptyRxQueueDfc->Enque(); |
|
547 break; |
|
548 } |
|
549 case EP2PAsyncConnectionLost: |
|
550 { |
|
551 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x EP2PAsyncConnectionLost" ), this, iShP2PProtocolId ) ); |
|
552 // If the connection is already lost when function is called return immediately. |
|
553 // This might happend in between calls to ::Open and ::NotifyClose |
|
554 if( !iRouterIf->ConnectionExist( iShP2PProtocolId ) ) |
|
555 { |
|
556 EnqueChannelRequestCompleteDfc( EP2PAsyncConnectionLost, KErrNotReady ); |
|
557 ResetQueues(); |
|
558 //Closing( iP2PProtocolId ); |
|
559 } |
|
560 break; |
|
561 } |
|
562 default: |
|
563 { |
|
564 ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest5 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
565 break; |
|
566 } |
|
567 } |
|
568 } |
|
569 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x %d<" ), this, iShP2PProtocolId, aRequest ) ); |
|
570 |
|
571 } |
|
572 |
|
573 TInt DP2PUserChannel::HandleSyncRequest( |
|
574 TInt aRequest, |
|
575 TAny* a1 |
|
576 ) |
|
577 { |
|
578 |
|
579 C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x %d>" ), this, iShP2PProtocolId, aRequest ) ); |
|
580 ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext5 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
581 TInt error( KErrNotSupported ); |
|
582 switch( aRequest ) |
|
583 { |
|
584 case EP2PClose: |
|
585 { |
|
586 C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x EP2PClose" ), this, iShP2PProtocolId ) ); |
|
587 Closing(); |
|
588 error = KErrNone; |
|
589 break; |
|
590 } |
|
591 case EP2PSend: |
|
592 { |
|
593 C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x EP2PSend" ), this, iShP2PProtocolId ) ); |
|
594 TUint32* tablePtr = reinterpret_cast<TUint32*>( a1 ); |
|
595 TAny* firstParam = reinterpret_cast<TAny*>( tablePtr[ KFirstParam ] ); |
|
596 TRACE_ASSERT_INFO( firstParam, ( (TUint8)iShP2PProtocolId << KProtocolIdShift | ( EP2PUserChannelNullParam2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ) ); |
|
597 TInt msgLength( Kern::ThreadGetDesLength( iThread, firstParam ) ); |
|
598 C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x EP2PSend 0x%x %d" ), this, iShP2PProtocolId, firstParam, msgLength ) ); |
|
599 if( msgLength > 0 && msgLength < KP2PMaximumSendSize ) |
|
600 { |
|
601 TDes8& sendBlock = MemApi::AllocBlock( msgLength ); |
|
602 ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, firstParam, sendBlock, 0, KChunkShiftBy0 ), ( EP2PUserChannelDesReadFailed | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
603 TRACE_ASSERT_INFO( sendBlock.Length() == msgLength, (TUint8)iShP2PProtocolId << KProtocolIdShift ); |
|
604 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest EP2PAsyncSend 0x%x 0x%x 0x%x" ), this, iShP2PProtocolId, &sendBlock ) ); |
|
605 error = iRouterIf->Send( sendBlock, iShP2PProtocolId ); |
|
606 } |
|
607 else |
|
608 { |
|
609 error = ( msgLength > KP2PMaximumSendSize ) ? KErrNoMemory : KErrBadDescriptor; |
|
610 TRACE_ASSERT_INFO( 0, (TUint8)iShP2PProtocolId << KProtocolIdShift | (TUint16)msgLength ); |
|
611 } |
|
612 break; |
|
613 } |
|
614 default: |
|
615 { |
|
616 ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest6 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
617 break; |
|
618 } |
|
619 } |
|
620 C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x %d ret %d<" ), this, iShP2PProtocolId, aRequest, error ) ); |
|
621 return error; |
|
622 |
|
623 } |
|
624 |
|
625 void DP2PUserChannel::DoCancel( |
|
626 TInt aRequest, |
|
627 TInt aMask ) |
|
628 { |
|
629 |
|
630 C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x>" ), this, iShP2PProtocolId ) ); |
|
631 switch( aMask&aRequest ) |
|
632 { |
|
633 case EP2PAsyncReceive: |
|
634 { |
|
635 C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x EP2PAsyncReceive 0x%x " ), this, iShP2PProtocolId, iReceiveBufPtr ) ); |
|
636 iReceiveBufPtr = NULL; |
|
637 break; |
|
638 } |
|
639 case EP2PAsyncOpen: |
|
640 { |
|
641 // Just complete with cancel |
|
642 C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x EP2PAsyncOpen" ), this, iShP2PProtocolId ) ); |
|
643 TInt err( Kern::MutexWait( *iShP2PProtocolIdMutex ) ); |
|
644 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed4 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
645 Close( ~iShP2PProtocolId ); |
|
646 Kern::MutexSignal( *iShP2PProtocolIdMutex ); |
|
647 break; |
|
648 } |
|
649 default: |
|
650 { |
|
651 ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest7 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ); |
|
652 break; |
|
653 } |
|
654 } |
|
655 EnqueChannelRequestCompleteDfc( aMask&aRequest, KErrCancel ); |
|
656 C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x<" ), this, iShP2PProtocolId ) ); |
|
657 |
|
658 } |
|
659 |
|
660 // Internal class start |
|
661 DP2PUserChannel::TP2PReq::TP2PReq() |
|
662 :iRequest( EP2PLastAsyncRequest ), iCompleteStatus( KRequestPending ) |
|
663 { |
|
664 } |
|
665 |
|
666 DP2PUserChannel::TP2PReq::TP2PReq( TP2PAsyncRequest aReq, TInt aStat ) |
|
667 :iRequest( aReq), iCompleteStatus( aStat ) |
|
668 { |
|
669 ASSERT_RESET_ALWAYS( iRequest != EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueOutOfSync | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
670 ASSERT_RESET_ALWAYS( iCompleteStatus != KRequestPending, ( EP2PUserChannelReqQueueOutOfSync1 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
671 } |
|
672 |
|
673 DP2PUserChannel::DP2PReqQueue::DP2PReqQueue() |
|
674 { |
|
675 C_TRACE( ( _T( "DP2PReqQueue::DP2PReqQueue 0x%x %d>" ), this ) ); |
|
676 iQueueMutex = new NFastMutex(); |
|
677 ASSERT_RESET_ALWAYS( iQueueMutex, ( EP2PUserChannelReqQueueMemoryAllocFailure | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
678 iSize = EP2PLastAsyncRequest; |
|
679 ASSERT_RESET_ALWAYS( ( iSize > 0 ), ( EP2PUserChannelReqQueueOutOfSync2 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
680 iShInputIndex = 0; |
|
681 iShOutputIndex = 0; |
|
682 iShCount = 0; |
|
683 for( TInt i( 0 ); i < iSize; ++i ) |
|
684 { |
|
685 iShReqRingBuffer[ i ].iRequest = EP2PLastAsyncRequest; |
|
686 iShReqRingBuffer[ i ].iCompleteStatus = KRequestPending; |
|
687 iShReqList[ i ] = NULL; |
|
688 } |
|
689 C_TRACE( ( _T( "DP2PReqQueue::DP2PReqQueue 0x%x<" ), this ) ); |
|
690 } |
|
691 |
|
692 DP2PUserChannel::DP2PReqQueue::~DP2PReqQueue() |
|
693 { |
|
694 C_TRACE( ( _T( "DP2PReqQueue::~DP2PReqQueue 0x%x %d>" ), this, iShCount ) ); |
|
695 // NOTE! This don't deallocate the blocks from the allocated memory just the pointers! |
|
696 ASSERT_RESET_ALWAYS( iShCount == 0, ( EP2PUserChannelReqQueueOutOfSync3 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
697 for( TInt i( 0 ); i < iSize; ++i ) |
|
698 { |
|
699 iShReqRingBuffer[ i ].iRequest = EP2PLastAsyncRequest; |
|
700 iShReqRingBuffer[ i ].iCompleteStatus = KRequestPending; |
|
701 iShReqList[ i ] = NULL; |
|
702 } |
|
703 iSize = 0; |
|
704 iShInputIndex = 0; |
|
705 iShOutputIndex = 0; |
|
706 iShCount = 0; |
|
707 if( iQueueMutex ) |
|
708 { |
|
709 C_TRACE( ( _T( "DP2PReqQueue::~DP2PReqQueue iQueueMutex" ) ) ); |
|
710 delete iQueueMutex; |
|
711 iQueueMutex = NULL; |
|
712 } |
|
713 C_TRACE( ( _T( "DP2PReqQueue::~DP2PReqQueue 0x%x<" ), this ) ); |
|
714 } |
|
715 |
|
716 /* |
|
717 * In case of queue overflow throw kern::fault |
|
718 */ |
|
719 TBool DP2PUserChannel::DP2PReqQueue::Add( TP2PReq aReq ) |
|
720 { |
|
721 C_TRACE( ( _T( "DP2PReqQueue::Add 0x%x %d %d %d %d>" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex ) ); |
|
722 TBool ok( EFalse ); |
|
723 NKern::FMWait( iQueueMutex ); |
|
724 // If queue get's overfilled throw kernel fault. |
|
725 ASSERT_RESET_ALWAYS( ( iShCount < iSize ), ( EP2PUserChannelReqQueueOutOfSync4 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
726 ASSERT_RESET_ALWAYS( EP2PLastAsyncRequest > aReq.iRequest, ( EP2PUserChannelReqQueueOverTheLimits | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
727 if( iShReqList[ aReq.iRequest ] ) |
|
728 { |
|
729 // Place the buffer into the queue. |
|
730 iShReqRingBuffer[ iShInputIndex ] = aReq; |
|
731 // Adjust input pointer. |
|
732 iShInputIndex = ( ( iShInputIndex + 1 ) % iSize ); |
|
733 // Remember the amount of the requests in the queue. |
|
734 iShCount++; |
|
735 ok = ETrue; |
|
736 } |
|
737 NKern::FMSignal( iQueueMutex ); |
|
738 C_TRACE( ( _T( "DP2PReqQueue::Add 0x%x %d %d %d %d %d<" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex, ok ) ); |
|
739 return ok; |
|
740 } |
|
741 |
|
742 /* |
|
743 *Returns the first pointer ( iShOutputIndex ) from the ring buffer. |
|
744 */ |
|
745 TBool DP2PUserChannel::DP2PReqQueue::Empty() |
|
746 { |
|
747 C_TRACE( ( _T( "DP2PReqQueue::Empty 0x%x %d<>" ), this, iShCount ) ); |
|
748 return iShCount == 0 ? ETrue : EFalse; |
|
749 |
|
750 } |
|
751 |
|
752 /* |
|
753 *Returns the first pointer ( iShOutputIndex ) from the ring buffer. |
|
754 */ |
|
755 DP2PUserChannel::TP2PReq DP2PUserChannel::DP2PReqQueue::Get() |
|
756 { |
|
757 C_TRACE( ( _T( "DP2PReqQueue::Get 0x%x %d %d %d %d>" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex ) ); |
|
758 NKern::FMWait( iQueueMutex ); |
|
759 // If queue is empty. |
|
760 ASSERT_RESET_ALWAYS( ( iShCount > 0 ), ( EP2PUserChannelReqQueueOutOfSync5 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
761 // Get the buffer from the queue. |
|
762 ASSERT_RESET_ALWAYS( EP2PLastAsyncRequest > iShOutputIndex, ( EP2PUserChannelReqQueueOverTheLimits2 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
763 TP2PReq temp = iShReqRingBuffer[ iShOutputIndex ]; |
|
764 // Set buffer location to NULL. |
|
765 iShReqRingBuffer[ iShOutputIndex ].iRequest = EP2PLastAsyncRequest; |
|
766 iShReqRingBuffer[ iShOutputIndex ].iCompleteStatus = KRequestPending; |
|
767 // Adjust output pointer. |
|
768 iShOutputIndex = ( ( iShOutputIndex + 1 ) % iSize ); |
|
769 // Remember the amount of the requests in the queue. |
|
770 iShCount--; |
|
771 NKern::FMSignal( iQueueMutex ); |
|
772 ASSERT_RESET_ALWAYS( temp.iRequest != EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueOutOfSync6 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
773 ASSERT_RESET_ALWAYS( temp.iCompleteStatus != KRequestPending, ( EP2PUserChannelReqQueueOutOfSync7 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
774 C_TRACE( ( _T( "DQueue::Get 0x%x %d %d %d %d<" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex ) ); |
|
775 return temp; |
|
776 } |
|
777 |
|
778 /* |
|
779 * Set req active / deactive. Default deactive. |
|
780 */ |
|
781 void DP2PUserChannel::DP2PReqQueue::SetReq( TP2PAsyncRequest aReqToSet, TRequestStatus* aStatus ) |
|
782 { |
|
783 C_TRACE( ( _T( "DP2PReqQueue::SetReq 0x%x %d 0x%x>" ), this, aReqToSet, aStatus ) ); |
|
784 ASSERT_RESET_ALWAYS( aReqToSet < EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueWrongRequest | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
785 // If setting same request twice. |
|
786 C_TRACE( ( _T( "DP2PReqQueue::SetReq 0x%x %d 0x%x 0x%x TBR" ), this, aReqToSet, aStatus, iShReqList[ aReqToSet ] ) ); |
|
787 ASSERT_RESET_ALWAYS( !( !iShReqList[ aReqToSet ] && aStatus == NULL ), EP2PUserChannelReqQueueCommon ); |
|
788 iShReqList[ aReqToSet ] = aStatus; |
|
789 C_TRACE( ( _T( "DP2PReqQueue::SetReq 0x%x %d 0x%x<" ), this, aReqToSet, aStatus ) ); |
|
790 } |
|
791 |
|
792 /* |
|
793 * Set req active / deactive. Default deactive. |
|
794 */ |
|
795 TRequestStatus* DP2PUserChannel::DP2PReqQueue::GetReq( TP2PAsyncRequest aReqToGet ) |
|
796 { |
|
797 ASSERT_RESET_ALWAYS( aReqToGet < EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueWrongRequest2 | EDP2PReqQueueId << KClassIdentifierShift ) ); |
|
798 C_TRACE( ( _T( "DP2PReqQueue::GetReq 0x%x 0x%x %d<>" ), this, iShReqList[ aReqToGet ], aReqToGet ) ); |
|
799 TRequestStatus* tmpStatus = iShReqList[ aReqToGet ]; |
|
800 return tmpStatus; |
|
801 } |
|
802 // Internal class end |