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