|
1 /* |
|
2 * Copyright (c) 2005 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 "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: An example implementation for ISC Driver Reference |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 |
|
22 #include <kernel.h> |
|
23 #include <kern_priv.h> |
|
24 #include <IscDataTransmissionBase.h> |
|
25 #include <IscMultiplexerBase.h> |
|
26 |
|
27 #include "IscMainRcvBuffer.h" |
|
28 #include "IscQueue.h" |
|
29 #include "IscSendQueue.h" |
|
30 #include "IscDevice.h" |
|
31 #include "IscChannel.h" |
|
32 #include "IscChannelContainer.h" |
|
33 #include "IscTrace.h" |
|
34 |
|
35 #ifdef __WINS__ |
|
36 #include <windows.h> |
|
37 #endif |
|
38 |
|
39 |
|
40 // EXTERNAL DATA STRUCTURES |
|
41 |
|
42 // EXTERNAL FUNCTION PROTOTYPES |
|
43 |
|
44 // CONSTANTS |
|
45 _LIT( KIscDriverName, "IscDriver" ); |
|
46 |
|
47 // MACROS |
|
48 |
|
49 // LOCAL CONSTANTS AND MACROS |
|
50 const TInt KSendDfcPriority( 4 ); |
|
51 const TInt KNotifyDfcPriority( 5 ); |
|
52 const TInt KIscInterruptLevelTwo( 2 ); |
|
53 |
|
54 // MODULE DATA STRUCTURES |
|
55 |
|
56 // LOCAL FUNCTION PROTOTYPES |
|
57 |
|
58 // FORWARD DECLARATIONS |
|
59 |
|
60 |
|
61 DIscDataTransmissionBase* DIscDevice::iIscDataTransmissionInterface = NULL; |
|
62 DIscMultiplexerBase* DIscDevice::iIscMultiplexerInterface = NULL; |
|
63 DIscSendQueue* DIscDevice::iSendQueue=NULL; |
|
64 DIscSendQueue* DIscDevice::iTempQueue=NULL; |
|
65 DIscSendQueue* DIscDevice::iControlSendQueue=NULL; |
|
66 TDfc* DIscDevice::iSendDfc = NULL; |
|
67 TDfc* DIscDevice::iNotifyDfc = NULL; |
|
68 TInt DIscDevice::iConnectionStatus = EIscConnectionNotOk; |
|
69 |
|
70 #ifdef __WINS__ |
|
71 CRITICAL_SECTION g_IscDTBCriticalSection; |
|
72 #endif |
|
73 |
|
74 // ============================ MEMBER FUNCTIONS =============================== |
|
75 |
|
76 |
|
77 // ----------------------------------------------------------------------------- |
|
78 // DIscDevice::DIscDevice |
|
79 // C++ default constructor |
|
80 // ( other items were commented in a header ). |
|
81 // ----------------------------------------------------------------------------- |
|
82 // |
|
83 EXPORT_C DIscDevice::DIscDevice() |
|
84 :DLogicalDevice(), |
|
85 iSend( NULL ), |
|
86 iTempSend( NULL ), |
|
87 iControlSend( NULL ), |
|
88 iSendFrameParameters( NULL ), |
|
89 iTempFrameParameters( NULL ), |
|
90 iControlFrameParameters( NULL ), |
|
91 iIscMainRcvBuffer( NULL ) |
|
92 { |
|
93 C_TRACE( ( _T( "DIscDevice::DIscDevice()" ) ) ); |
|
94 |
|
95 iVersion = TVersion( KMajorVersionNumber, KMinorVersionNumber, |
|
96 KBuildVersionNumber ); |
|
97 iParseMask |= KDeviceAllowUnit; |
|
98 iParseMask |= KDeviceAllowInfo; |
|
99 |
|
100 #ifdef __WINS__ |
|
101 InitializeCriticalSection( &g_IscDTBCriticalSection ); |
|
102 #endif |
|
103 } |
|
104 |
|
105 // Destructor |
|
106 EXPORT_C DIscDevice::~DIscDevice() |
|
107 { |
|
108 C_TRACE( ( _T( "DIscDevice::~DIscDevice()" ) ) ); |
|
109 |
|
110 IscChannelContainer::DeActivate(); |
|
111 |
|
112 if ( iIscMainRcvBuffer ) |
|
113 { |
|
114 delete iIscMainRcvBuffer; |
|
115 iIscMainRcvBuffer = NULL; |
|
116 } |
|
117 |
|
118 |
|
119 iIscDataTransmissionInterface = NULL; |
|
120 iIscMultiplexerInterface = NULL; |
|
121 |
|
122 delete iTempSend; |
|
123 delete iControlSend; |
|
124 delete iSendQueue; |
|
125 delete iTempQueue; |
|
126 delete iControlSendQueue; |
|
127 delete iSendDfc; |
|
128 delete iNotifyDfc; |
|
129 |
|
130 #ifdef __WINS__ |
|
131 DeleteCriticalSection( &g_IscDTBCriticalSection ); |
|
132 #endif |
|
133 |
|
134 } |
|
135 |
|
136 |
|
137 // ----------------------------------------------------------------------------- |
|
138 // DIscDevice::Install |
|
139 // Complete the installation of driver |
|
140 // ( other items were commented in a header ). |
|
141 // ----------------------------------------------------------------------------- |
|
142 // |
|
143 TInt DIscDevice::Install() |
|
144 { |
|
145 C_TRACE( ( _T( "DIscDevice::Install()" ) ) ); |
|
146 |
|
147 // Dfc for sending frames |
|
148 iSendDfc = new TDfc( Flush, this, Kern::DfcQue0(), KSendDfcPriority ); |
|
149 iNotifyDfc = new TDfc( NotifyConnection, this, Kern::DfcQue0(), KNotifyDfcPriority ); |
|
150 ASSERT_RESET_ALWAYS( iSendDfc, "IscDriver",EIscMemoryAllocationFailure ); |
|
151 |
|
152 //Initialize IscChannelContainer |
|
153 IscChannelContainer::Initialize(); |
|
154 |
|
155 // connect to multiplexer and data transmission driver |
|
156 TInt r = InitializeLdd2LddInterface(); |
|
157 if ( r != KErrNone ) |
|
158 { |
|
159 TRACE_ASSERT_ALWAYS; |
|
160 return r; |
|
161 } |
|
162 |
|
163 return ( SetName( &KIscDriverName ) ); |
|
164 } |
|
165 |
|
166 // ----------------------------------------------------------------------------- |
|
167 // DIscDevice::Initialize |
|
168 // Complete the initialization of driver |
|
169 // ( other items were commented in a header ). |
|
170 // ----------------------------------------------------------------------------- |
|
171 // |
|
172 void DIscDevice::Initialize() |
|
173 { |
|
174 C_TRACE( ( _T( "DIscDevice::Initialize()" ) ) ); |
|
175 |
|
176 TInt i( 0 ); |
|
177 |
|
178 // Get buffer configuration data from multiplexer |
|
179 TIscConfiguration configData; |
|
180 iIscMultiplexerInterface->GetConfiguration( configData ); |
|
181 |
|
182 // Create main buffer |
|
183 iIscMainRcvBuffer = new DIscMainRcvBuffer( this, configData.mainRcvQueueSize ); |
|
184 ASSERT_RESET_ALWAYS( iIscMainRcvBuffer, "IscDriver",EIscMemoryAllocationFailure ); |
|
185 |
|
186 // Do second phase installation |
|
187 iIscMainRcvBuffer->DoCreate(); |
|
188 |
|
189 // Create queue for sending frames |
|
190 iSend = new TUint32*[configData.channelSendQueueSize]; |
|
191 ASSERT_RESET_ALWAYS( iSend, "IscDriver",EIscMemoryAllocationFailure ); |
|
192 |
|
193 iSendFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize]; |
|
194 for ( i = 0; i < configData.channelSendQueueSize; i++ ) |
|
195 { |
|
196 iSendFrameParameters[i] = new TIscSendFrameInfo; |
|
197 } |
|
198 ASSERT_RESET_ALWAYS( iSendFrameParameters, "IscDriver",EIscMemoryAllocationFailure ); |
|
199 |
|
200 iSendQueue = new DIscSendQueue( iSend, iSendFrameParameters, configData.channelSendQueueSize ); |
|
201 ASSERT_RESET_ALWAYS( iSendQueue, "IscDriver",EIscMemoryAllocationFailure ); |
|
202 |
|
203 |
|
204 // create temporary queue |
|
205 iTempSend = new TUint32*[configData.channelSendQueueSize]; |
|
206 ASSERT_RESET_ALWAYS( iTempSend, "IscDriver",EIscMemoryAllocationFailure ); |
|
207 |
|
208 iTempFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize]; |
|
209 for ( i =0; i < configData.channelSendQueueSize; i++ ) |
|
210 { |
|
211 iTempFrameParameters[i] = new TIscSendFrameInfo; |
|
212 } |
|
213 ASSERT_RESET_ALWAYS( iTempFrameParameters, "IscDriver",EIscMemoryAllocationFailure ); |
|
214 |
|
215 iTempQueue = new DIscSendQueue( iTempSend, iTempFrameParameters, configData.channelSendQueueSize ); |
|
216 ASSERT_RESET_ALWAYS( iTempQueue, "IscDriver",EIscMemoryAllocationFailure ); |
|
217 |
|
218 |
|
219 // Create send queue for control channel |
|
220 iControlSend = new TUint32*[configData.channelSendQueueSize]; |
|
221 ASSERT_RESET_ALWAYS( iControlSend, "IscDriver",EIscMemoryAllocationFailure ); |
|
222 |
|
223 iControlFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize]; |
|
224 for ( i = 0; i < configData.channelSendQueueSize; i++ ) |
|
225 { |
|
226 iControlFrameParameters[i] = new TIscSendFrameInfo; |
|
227 } |
|
228 ASSERT_RESET_ALWAYS( iControlFrameParameters, "IscDriver",EIscMemoryAllocationFailure ); |
|
229 |
|
230 iControlSendQueue = new DIscSendQueue( iControlSend, iControlFrameParameters, configData.channelSendQueueSize ); |
|
231 ASSERT_RESET_ALWAYS( iControlSendQueue, "IscDriver",EIscMemoryAllocationFailure ); |
|
232 |
|
233 iIscDataTransmissionInterface->AllocBuffers( configData.bufferConfig ); |
|
234 |
|
235 iConnectionStatus = iIscDataTransmissionInterface->ConnectionStatus(); |
|
236 |
|
237 iIscMultiplexerInterface->NotifyConnectionStatus( iConnectionStatus ); |
|
238 C_TRACE( ( _T( "DIscDevice::Initialize - return void" ) ) ); |
|
239 } |
|
240 // ----------------------------------------------------------------------------- |
|
241 // DIscDevice::GetCaps |
|
242 // |
|
243 // ( other items were commented in a header ). |
|
244 // ----------------------------------------------------------------------------- |
|
245 // |
|
246 EXPORT_C void DIscDevice::GetCaps( |
|
247 TDes8& /*aDes*/ ) const |
|
248 { |
|
249 // GetCaps implemented to keep compiler happy |
|
250 } |
|
251 |
|
252 // ----------------------------------------------------------------------------- |
|
253 // DEcsDevice::Create |
|
254 // From DLogicalDevice |
|
255 // ( other items were commented in a header ). |
|
256 // ----------------------------------------------------------------------------- |
|
257 // |
|
258 TInt DIscDevice::Create( |
|
259 DLogicalChannelBase*& aChannel ) |
|
260 { |
|
261 aChannel=new DIscChannel( this ); |
|
262 return aChannel?KErrNone:KErrNoMemory; |
|
263 } |
|
264 |
|
265 // ----------------------------------------------------------------------------- |
|
266 // DIscDevice::Receive |
|
267 // Frames coming from Domestic OS |
|
268 // ( other items were commented in a header ). |
|
269 // ----------------------------------------------------------------------------- |
|
270 // |
|
271 EXPORT_C void DIscDevice::Receive( |
|
272 TDesC8* aData ) const |
|
273 { |
|
274 DIscMainRcvBuffer::MsgReceive( aData ); |
|
275 } |
|
276 |
|
277 |
|
278 // ----------------------------------------------------------------------------- |
|
279 // DIscDevice::ReserveMemoryBlock |
|
280 // Get message block from buffers allocated in IscDataTransmissionBase.dll |
|
281 // ( other items were commented in a header ). |
|
282 // ----------------------------------------------------------------------------- |
|
283 // |
|
284 EXPORT_C void DIscDevice::ReserveMemoryBlock( TDes8*& aPtr, TUint16 aSize ) |
|
285 { |
|
286 iIscDataTransmissionInterface->ReserveMemoryBlock( aPtr, aSize ); |
|
287 } |
|
288 |
|
289 // ----------------------------------------------------------------------------- |
|
290 // DIscDevice::ReleaseMemoryBlock |
|
291 // Release memory block allocated with ReserveMemoryBlock |
|
292 // ( other items were commented in a header ). |
|
293 // ----------------------------------------------------------------------------- |
|
294 // |
|
295 EXPORT_C void DIscDevice::ReleaseMemoryBlock( |
|
296 TDes8* aPtr ) |
|
297 { |
|
298 C_TRACE( ( _T( "DIscDevice::ReleaseMemoryBlock(0x%x)" ), aPtr ) ); |
|
299 |
|
300 if ( iIscDataTransmissionInterface ) |
|
301 { |
|
302 iIscDataTransmissionInterface->ReleaseMemoryBlock( aPtr ); |
|
303 } |
|
304 } |
|
305 |
|
306 // ----------------------------------------------------------------------------- |
|
307 // DIscDevice::NotifyConnectionStatus |
|
308 // Connection status change function |
|
309 // ( other items were commented in a header ). |
|
310 // ----------------------------------------------------------------------------- |
|
311 // |
|
312 EXPORT_C void DIscDevice::NotifyConnectionStatus( const TInt aStatus ) |
|
313 { |
|
314 C_TRACE( ( _T( "DIscDevice::NotifyConnectionStatus(0x%x)" ), aStatus ) ); |
|
315 if ( iConnectionStatus != aStatus ) |
|
316 { |
|
317 iConnectionStatus = aStatus; |
|
318 if ( NKern::CurrentContext() == NKern::EInterrupt ) |
|
319 { |
|
320 iNotifyDfc->Add(); |
|
321 } |
|
322 else |
|
323 { |
|
324 iNotifyDfc->Enque(); |
|
325 } |
|
326 } |
|
327 |
|
328 C_TRACE( ( _T( "DIscDevice::NotifyConnectionStatus() return" ) ) ); |
|
329 } |
|
330 |
|
331 // ----------------------------------------------------------------------------- |
|
332 // DIscDevice::NotifyConnection |
|
333 // Connection status change DFC function. |
|
334 // ( other items were commented in a header ). |
|
335 // ----------------------------------------------------------------------------- |
|
336 // |
|
337 void DIscDevice::NotifyConnection( TAny* ) |
|
338 { |
|
339 C_TRACE( ( _T( "DIscDevice::NotifyConnection(0x%x)" ), iConnectionStatus ) ); |
|
340 |
|
341 iIscMultiplexerInterface->NotifyConnectionStatus( iConnectionStatus ); |
|
342 DIscChannel* tempPtr = NULL; |
|
343 for ( TUint16 i = KIscFirstChannel; i < KIscNumberOfUnits; i++ ) |
|
344 { |
|
345 for ( TUint16 ii( 0 ); ii < KIscMaxNumberOfChannelSharers; ii++ ) |
|
346 { |
|
347 tempPtr = IscChannelContainer::Channel( i, ii ); |
|
348 if ( tempPtr ) |
|
349 { |
|
350 tempPtr->NotifyConnectionStatus( iConnectionStatus ); |
|
351 tempPtr = NULL; |
|
352 } |
|
353 } |
|
354 } |
|
355 C_TRACE( ( _T( "DIscDevice::NotifyConnection() return" ) ) ); |
|
356 |
|
357 } |
|
358 |
|
359 // ----------------------------------------------------------------------------- |
|
360 // DIscDevice::ULFlowControl |
|
361 // Function to notify client about uplink flow control status |
|
362 // ( other items were commented in a header ). |
|
363 // ----------------------------------------------------------------------------- |
|
364 // |
|
365 EXPORT_C void DIscDevice::ULFlowControl( |
|
366 const TInt aULFlowStatus, |
|
367 const TUint16 aChannelId, |
|
368 const TAny* aChannelPtr ) |
|
369 { |
|
370 C_TRACE( ( _T( "DIscDevice::ULFlowControl(0x%x, 0x%x, 0x%x)" ), aULFlowStatus, aChannelId, aChannelPtr ) ); |
|
371 |
|
372 DIscChannel* tempPtr = NULL; |
|
373 TBool channelFound(EFalse); |
|
374 |
|
375 if ( !aChannelPtr ) |
|
376 { |
|
377 // All channels. |
|
378 for ( TUint16 i(0); i < KIscMaxNumberOfChannelSharers; i++ ) |
|
379 { |
|
380 tempPtr = IscChannelContainer::Channel( aChannelId, i ); |
|
381 if ( tempPtr ) |
|
382 { |
|
383 tempPtr->NotifyFlowControl( aULFlowStatus ); |
|
384 tempPtr = NULL; |
|
385 channelFound = ETrue; |
|
386 } |
|
387 else |
|
388 { |
|
389 //Do nothing |
|
390 } |
|
391 } |
|
392 } |
|
393 else |
|
394 { |
|
395 // Single channel. |
|
396 for ( TUint16 i(0); i < KIscMaxNumberOfChannelSharers; i++ ) |
|
397 { |
|
398 tempPtr = IscChannelContainer::Channel( aChannelId, i ); |
|
399 if ( tempPtr == ( DIscChannel* )aChannelPtr ) |
|
400 { |
|
401 tempPtr->NotifyFlowControl( aULFlowStatus ); |
|
402 tempPtr = NULL; |
|
403 channelFound = ETrue; |
|
404 break; |
|
405 } |
|
406 else |
|
407 { |
|
408 //Do nothing |
|
409 } |
|
410 } |
|
411 } |
|
412 |
|
413 if ( channelFound == EFalse ) |
|
414 TRACE_ASSERT_ALWAYS; |
|
415 |
|
416 } |
|
417 |
|
418 // ----------------------------------------------------------------------------- |
|
419 // DIscDevice::IsPending |
|
420 // Function to check if asycnhronous request is active |
|
421 // ( other items were commented in a header ). |
|
422 // ----------------------------------------------------------------------------- |
|
423 // |
|
424 EXPORT_C TInt DIscDevice::IsPending( |
|
425 const TUint16 aReqNumber, |
|
426 const TAny* aChannelPtr ) |
|
427 { |
|
428 C_TRACE( ( _T( "DIscDevice::IsPending(0x%x, 0x%x)" ), aReqNumber, aChannelPtr ) ); |
|
429 |
|
430 DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; |
|
431 TInt error = IscChannelContainer::ValidateChannel( tempPtr ); |
|
432 if( error == KErrNone ) |
|
433 { |
|
434 error = tempPtr->IsPending( aReqNumber ); |
|
435 } |
|
436 C_TRACE( ( _T( "DIscDevice::IsPending - return %d" ), error ) ); |
|
437 return error; |
|
438 |
|
439 } |
|
440 |
|
441 // ----------------------------------------------------------------------------- |
|
442 // DIscDevice::DLFlowControl |
|
443 // Notify multiplexer about down link flow control |
|
444 // ( other items were commented in a header ). |
|
445 // ----------------------------------------------------------------------------- |
|
446 // |
|
447 void DIscDevice::DLFlowControlNotify( |
|
448 const TInt aDLFlowStatus, |
|
449 const TUint16 aChannel, |
|
450 const TAny* aChannelPtr ) |
|
451 { |
|
452 C_TRACE( ( _T( "DIscDevice::DLFlowControlNotify(0x%x, 0x%x)" ), aDLFlowStatus, aChannel ) ); |
|
453 if ( aChannel >= KIscFirstChannel |
|
454 && aChannel < KIscNumberOfUnits ) |
|
455 { |
|
456 if ( aDLFlowStatus == EIscFlowControlOn ) |
|
457 { |
|
458 iIscMultiplexerInterface->DLFlowControl( EIscFlowControlOn, aChannel, aChannelPtr ); |
|
459 } |
|
460 else |
|
461 { |
|
462 iIscMultiplexerInterface->DLFlowControl( EIscFlowControlOff, aChannel, aChannelPtr ); |
|
463 } |
|
464 } |
|
465 else |
|
466 { |
|
467 |
|
468 if ( aChannel == 0x00 ) |
|
469 { |
|
470 // control channel, no flow control used |
|
471 } |
|
472 else |
|
473 { |
|
474 // should never came here |
|
475 TRACE_ASSERT_ALWAYS; |
|
476 } |
|
477 } |
|
478 } |
|
479 |
|
480 // ----------------------------------------------------------------------------- |
|
481 // DIscDevice::InitializeLdd2LddInterface |
|
482 // Function to connect to DataTransmission and Multiplexer ldds |
|
483 // ( other items were commented in a header ). |
|
484 // ----------------------------------------------------------------------------- |
|
485 // |
|
486 TInt DIscDevice::InitializeLdd2LddInterface() |
|
487 { |
|
488 C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface()" ) ) ); |
|
489 |
|
490 // Find pointer to second level LDD. |
|
491 DObjectCon* lDevices = Kern::Containers()[ ELogicalDevice ]; |
|
492 TKName driverName; |
|
493 ASSERT_RESET_ALWAYS( lDevices, "IscDriver", EIscLogicalDevicesNotFound ); |
|
494 |
|
495 TInt err( KErrNone ); |
|
496 //TInt driverHandle( KErrNone ); // API change in SOS9.2 WK08 |
|
497 TFindHandle driverHandle; |
|
498 // Find pointer to ISC Multiplexer. |
|
499 err = lDevices->FindByName( driverHandle, KIscMultiplexerName, driverName ); |
|
500 if( KErrNone != err ) |
|
501 { |
|
502 C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() ISC Multiplexer Not Found!" ) ) ); |
|
503 ASSERT_RESET_ALWAYS( 0, "IscDriver" ,EIscMultiplexerNotFound ); |
|
504 } |
|
505 |
|
506 iIscMultiplexerInterface = static_cast<DIscMultiplexerBase*>( lDevices->At( driverHandle ) ); |
|
507 ASSERT_RESET_ALWAYS( iIscMultiplexerInterface, "IscDriver", EIscMultiplexerNotFound ); |
|
508 |
|
509 //TInt secondDriverHandle( KErrNone ); // API change in SOS9.2 WK08 |
|
510 TFindHandle secondDriverHandle; |
|
511 // Find pointer to Data Transmission Plugin. |
|
512 err = lDevices->FindByName( secondDriverHandle, KIscDataTransmissionDriverName, driverName ); |
|
513 if( KErrNone != err ) |
|
514 { |
|
515 C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() Data Transmission Plug-In Not Found!" ) ) ); |
|
516 ASSERT_RESET_ALWAYS( 0, "IscDriver", EIscDataTransmissionDriverNotFound ); |
|
517 } |
|
518 |
|
519 iIscDataTransmissionInterface = static_cast<DIscDataTransmissionBase*>( lDevices->At( secondDriverHandle ) ); |
|
520 ASSERT_RESET_ALWAYS( iIscDataTransmissionInterface, "IscDriver", EIscDataTransmissionDriverNotFound ); |
|
521 |
|
522 iIscDataTransmissionInterface->Connect( this ); |
|
523 iIscMultiplexerInterface->Connect( this ); |
|
524 |
|
525 C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface - return 0x%x" ), err ) ); |
|
526 return err; |
|
527 |
|
528 } |
|
529 |
|
530 // ----------------------------------------------------------------------------- |
|
531 // DIscDevice::QueueFrame |
|
532 // Queue frames that will be sent to Domestic OS |
|
533 // ( other items were commented in a header ). |
|
534 // ----------------------------------------------------------------------------- |
|
535 // |
|
536 EXPORT_C TInt DIscDevice::QueueFrame( |
|
537 const TUint16 aChannelId, |
|
538 const TDesC8* aFrame, |
|
539 const TAny* aChannelPtr, |
|
540 TAny* aFrameInfo ) |
|
541 { |
|
542 C_TRACE( ( _T( "DIscDevice::QueueFrame(0x%x, 0x%x, 0x%x, 0x%x)" ), aChannelId, aFrame, aChannelPtr, aFrameInfo ) ); |
|
543 |
|
544 TInt error = KErrNone; |
|
545 |
|
546 // control channel frame ( highest priority ) |
|
547 if ( aChannelId == KIscControlChannel ) |
|
548 { |
|
549 C_TRACE( ( _T( "DIscDevice::QueueFrame control frame queue" ) ) ); |
|
550 //add to control frame queue |
|
551 error = iControlSendQueue->Add( ( TDes8* )aFrame, aChannelId, ( DIscChannel* )aChannelPtr, aFrameInfo ); |
|
552 } |
|
553 else |
|
554 { |
|
555 C_TRACE( ( _T( "DIscDevice::QueueFrame send queue" ) ) ); |
|
556 // add to send queue |
|
557 error = iSendQueue->Add( ( TDes8* )aFrame, aChannelId, ( DIscChannel* )aChannelPtr, aFrameInfo ); |
|
558 } |
|
559 |
|
560 C_TRACE( ( _T( "DIscDevice::QueueFrame - return 0x%x" ), error ) ); |
|
561 return error; |
|
562 } |
|
563 |
|
564 |
|
565 // ----------------------------------------------------------------------------- |
|
566 // DIscDevice::CancelSending |
|
567 // Cancels sending of frames to Domestic OS |
|
568 // ( other items were commented in a header ). |
|
569 // ----------------------------------------------------------------------------- |
|
570 // |
|
571 EXPORT_C TInt DIscDevice::CancelSending( const TUint16 aChannelId, const TAny* aChannelPtr ) |
|
572 { |
|
573 C_TRACE( ( _T( "DIscDevice::CancelSending - Caller is channel: %d (0x%x)" ), aChannelId, aChannelPtr ) ); |
|
574 |
|
575 TInt error( KErrNotFound ); |
|
576 TInt irqLevel( 0 ); |
|
577 |
|
578 TInt counterA( 0 ); |
|
579 TInt counterB( 0 ); |
|
580 |
|
581 TIscSendFrameInfo* temp = NULL; |
|
582 TDes8* frame = NULL; |
|
583 |
|
584 irqLevel = DisableIrqs(); |
|
585 |
|
586 if ( KIscControlChannel == aChannelId ) |
|
587 { |
|
588 // empty control send queue |
|
589 while ( !iControlSendQueue->Empty() ) |
|
590 { |
|
591 temp = iControlSendQueue->GetFirstFrameInfo(); |
|
592 frame = ( TDes8* )iControlSendQueue->RemoveFirst(); |
|
593 if ( temp && frame ) |
|
594 { |
|
595 if ( temp->iChannelId == aChannelId && |
|
596 temp->iChannelPtr == ( DIscChannel* )aChannelPtr ) |
|
597 { |
|
598 // sender found, no need to store the frame |
|
599 counterB++; |
|
600 } |
|
601 else |
|
602 { |
|
603 iTempQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); |
|
604 } |
|
605 } |
|
606 else |
|
607 { |
|
608 // should never came here |
|
609 TRACE_ASSERT_ALWAYS; |
|
610 } |
|
611 counterA++; |
|
612 temp = NULL; |
|
613 frame = NULL; |
|
614 } |
|
615 |
|
616 while ( !iTempQueue->Empty() ) |
|
617 { |
|
618 temp = iTempQueue->GetFirstFrameInfo(); |
|
619 frame = ( TDes8* )iTempQueue->RemoveFirst(); |
|
620 if ( temp && frame ) |
|
621 { |
|
622 iControlSendQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); |
|
623 } |
|
624 else |
|
625 { |
|
626 // should never came here |
|
627 TRACE_ASSERT_ALWAYS; |
|
628 } |
|
629 temp = NULL; |
|
630 frame = NULL; |
|
631 } |
|
632 } |
|
633 else |
|
634 { |
|
635 // empty normal send queue |
|
636 while ( !iSendQueue->Empty() ) |
|
637 { |
|
638 temp = iSendQueue->GetFirstFrameInfo(); |
|
639 frame = ( TDes8* )iSendQueue->RemoveFirst(); |
|
640 if ( temp && frame ) |
|
641 { |
|
642 if ( temp->iChannelId == aChannelId && |
|
643 temp->iChannelPtr == ( DIscChannel* )aChannelPtr ) |
|
644 { |
|
645 // sender found, no need to store frame |
|
646 counterB++; |
|
647 } |
|
648 else |
|
649 { |
|
650 iTempQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); |
|
651 } |
|
652 } |
|
653 else |
|
654 { |
|
655 // should never came here |
|
656 TRACE_ASSERT_ALWAYS; |
|
657 } |
|
658 counterA++; |
|
659 temp = NULL; |
|
660 frame = NULL; |
|
661 } |
|
662 |
|
663 while ( !iTempQueue->Empty() ) |
|
664 { |
|
665 temp = iTempQueue->GetFirstFrameInfo(); |
|
666 frame = ( TDes8* )iTempQueue->RemoveFirst(); |
|
667 if ( temp && frame ) |
|
668 { |
|
669 iSendQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo ); |
|
670 } |
|
671 else |
|
672 { |
|
673 // should never came here |
|
674 TRACE_ASSERT_ALWAYS; |
|
675 } |
|
676 |
|
677 temp = NULL; |
|
678 frame = NULL; |
|
679 } |
|
680 } |
|
681 |
|
682 RestoreIrqs( irqLevel ); |
|
683 |
|
684 C_TRACE( ( _T( "DIscDevice::CancelSending() - Frames in queue: Before: %d, After: %d" ), counterA, ( counterA-counterB ) ) ); |
|
685 C_TRACE( ( _T( "DIscDevice::CancelSending() - So channel 0x%x 0x%x had %d pending messages!" ), aChannelId, aChannelPtr, counterB ) ); |
|
686 |
|
687 // if there weren't any frames that were cancelled return KErrNotFound, otherwise return KErrNone |
|
688 if ( counterB > 0 ) |
|
689 { |
|
690 error = KErrNone; |
|
691 } |
|
692 |
|
693 return error; |
|
694 |
|
695 } |
|
696 |
|
697 // ----------------------------------------------------------------------------- |
|
698 // DIscDevice::FlushQueues |
|
699 // Adds Dfc to empty queues |
|
700 // ( other items were commented in a header ). |
|
701 // ----------------------------------------------------------------------------- |
|
702 // |
|
703 EXPORT_C void DIscDevice::FlushQueues() |
|
704 { |
|
705 C_TRACE( ( _T( "DIscDevice::FlushQueues()" ) ) ); |
|
706 |
|
707 if ( NKern::CurrentContext() == NKern::EInterrupt ) |
|
708 { |
|
709 iSendDfc->Add(); |
|
710 } |
|
711 else |
|
712 { |
|
713 iSendDfc->Enque(); |
|
714 } |
|
715 |
|
716 } |
|
717 |
|
718 // ----------------------------------------------------------------------------- |
|
719 // DIscDevice::CompleteRequest |
|
720 // Function to complete user side asynchronous request |
|
721 // ( other items were commented in a header ). |
|
722 // ----------------------------------------------------------------------------- |
|
723 // |
|
724 // This method has been modified to allow channel sharing between application. |
|
725 // The completion routine uses directly a pointer on a DLogicalChannel instead of a channel index |
|
726 // |
|
727 EXPORT_C void DIscDevice::CompleteRequest( |
|
728 TUint16 aOperation, |
|
729 TInt aCompleteStatus, |
|
730 const TAny* aChannelPtr ) |
|
731 { |
|
732 C_TRACE( ( _T( "DIscDevice::CompleteRequest(0x%x, 0x%x, 0x%x)" ), aOperation, aCompleteStatus, aChannelPtr ) ); |
|
733 |
|
734 DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; |
|
735 TInt error = IscChannelContainer::ValidateChannel( tempPtr ); |
|
736 if( error == KErrNone ) |
|
737 { |
|
738 tempPtr->CompleteRequest( aOperation, aCompleteStatus ); |
|
739 } |
|
740 |
|
741 C_TRACE( ( _T( "DIscDevice::CompleteRequest - return void" ) ) ); |
|
742 } |
|
743 |
|
744 // ----------------------------------------------------------------------------- |
|
745 // DIscDevice::CopyFromUserBuffer |
|
746 // |
|
747 // ( other items were commented in a header ). |
|
748 // ----------------------------------------------------------------------------- |
|
749 // |
|
750 EXPORT_C TInt DIscDevice::CopyFromUserBuffer( |
|
751 const TDesC8& aUserBuffer, |
|
752 TDes8& aKernelBuffer, |
|
753 const TAny* aChannelPtr, |
|
754 const TInt aOffset ) |
|
755 { |
|
756 C_TRACE( ( _T( "DIscDevice::CopyFromUserBuffer(0x%x, 0x%x, 0x%x, 0x%x)" ), &aUserBuffer, &aKernelBuffer, aChannelPtr, aOffset ) ); |
|
757 |
|
758 // Check if channel pointer is valid. |
|
759 DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; |
|
760 TInt error = IscChannelContainer::ValidateChannel( tempPtr ); |
|
761 if( error == KErrNone ) |
|
762 { |
|
763 error = tempPtr->CopyFromUserBuffer( aUserBuffer, aKernelBuffer, aOffset ); |
|
764 } |
|
765 C_TRACE( ( _T( "DIscDevice::CopyFromUserBuffer - return %d" ), error ) ); |
|
766 return error; |
|
767 |
|
768 } |
|
769 |
|
770 // ----------------------------------------------------------------------------- |
|
771 // DIscDevice::CopyToUserBuffer |
|
772 // |
|
773 // (other items were commented in a header). |
|
774 // ----------------------------------------------------------------------------- |
|
775 // |
|
776 EXPORT_C TInt DIscDevice::CopyToUserBuffer( |
|
777 TAny* aUserBuffer, |
|
778 const TDesC8& aKernelBuffer, |
|
779 const TAny* aChannelPtr, |
|
780 const TInt aOffset ) |
|
781 { |
|
782 C_TRACE( ( _T( "DIscDevice::CopyToUserBuffer(0x%x, 0x%x, 0x%x)" ), aUserBuffer, &aKernelBuffer, aChannelPtr ) ); |
|
783 |
|
784 DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; |
|
785 TInt error = IscChannelContainer::ValidateChannel( tempPtr ); |
|
786 if( KErrNone == error ) |
|
787 { |
|
788 error = tempPtr->ThreadWrite( aUserBuffer, &aKernelBuffer, aOffset ); |
|
789 } |
|
790 C_TRACE( ( _T( "DIscDevice::CopyToUserBuffer - return %d" ), error ) ); |
|
791 return error; |
|
792 |
|
793 } |
|
794 |
|
795 // ----------------------------------------------------------------------------- |
|
796 // DIscMultiplexerBase::GetThreadPtr |
|
797 // Returns user side thread. Ownership is not given. |
|
798 // ( other items were commented in a header ). |
|
799 // ----------------------------------------------------------------------------- |
|
800 // |
|
801 EXPORT_C DThread* DIscDevice::GetThreadPtr( const TAny* aChannelPtr ) |
|
802 { |
|
803 C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr(0x%x)" ), aChannelPtr ) ); |
|
804 DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr; |
|
805 TInt error = IscChannelContainer::ValidateChannel( tempPtr ); |
|
806 DThread* tmp = NULL; |
|
807 if( KErrNone == error ) |
|
808 { |
|
809 tmp = tempPtr->GetDThread(); |
|
810 } |
|
811 else |
|
812 { |
|
813 C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr failed return NULL" ) ) ); |
|
814 } |
|
815 C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr return 0x%x" ), tmp ) ); |
|
816 return tmp; |
|
817 |
|
818 } |
|
819 |
|
820 // ----------------------------------------------------------------------------- |
|
821 // DIscDevice::Flush |
|
822 // Dfc to empty control channel and other send queues |
|
823 // ( other items were commented in a header ). |
|
824 // ----------------------------------------------------------------------------- |
|
825 // |
|
826 void DIscDevice::Flush( TAny* aPtr ) |
|
827 { |
|
828 C_TRACE( ( _T( "DIscDevice::Flush(0x%x)" ), aPtr ) ); |
|
829 DIscDevice* device = ( DIscDevice* )aPtr; |
|
830 |
|
831 TDes8* frame = NULL; |
|
832 TIscSendFrameInfo* temp = NULL; |
|
833 |
|
834 TInt irqLevel(0); |
|
835 |
|
836 // If transmission is asynchronous and there can't be |
|
837 // several requests at the same time |
|
838 if ( !iIscDataTransmissionInterface->IsWritePending() ) |
|
839 { |
|
840 irqLevel = DisableIrqs(); |
|
841 if ( !iControlSendQueue->Empty() ) |
|
842 { |
|
843 temp = iControlSendQueue->GetFirstFrameInfo(); |
|
844 frame = ( TDes8* )iControlSendQueue->RemoveFirst(); |
|
845 } |
|
846 else |
|
847 { |
|
848 temp = iSendQueue->GetFirstFrameInfo(); |
|
849 frame = ( TDes8* )iSendQueue->RemoveFirst(); |
|
850 } |
|
851 RestoreIrqs( irqLevel ); |
|
852 C_TRACE( ( _T( "DIscDevice::Flush after RESTOREIRQS" ) ) ); |
|
853 if ( frame ) |
|
854 iIscDataTransmissionInterface->SendFrame( *frame, device->iSendDfc, temp->iFrameInfo ); |
|
855 } |
|
856 C_TRACE( ( _T( "DIscDevice::Flush - return 0x0" ) ) ); |
|
857 |
|
858 } |
|
859 |
|
860 |
|
861 // ----------------------------------------------------------------------------- |
|
862 // DIscDevice::ConnectionStatus |
|
863 // Function to tell current status of connection to Domestic OS |
|
864 // ( other items were commented in a header ). |
|
865 // ----------------------------------------------------------------------------- |
|
866 // |
|
867 TInt DIscDevice::ConnectionStatus() |
|
868 { |
|
869 return iConnectionStatus; |
|
870 } |
|
871 |
|
872 // ----------------------------------------------------------------------------- |
|
873 // DIscDevice::DisableIrqs |
|
874 // Function to disable interrupts |
|
875 // ( other items were commented in a header ). |
|
876 // ----------------------------------------------------------------------------- |
|
877 // |
|
878 TInt DIscDevice::DisableIrqs() |
|
879 { |
|
880 #ifndef __WINS__ |
|
881 return NKern::DisableInterrupts( KIscInterruptLevelTwo ); |
|
882 #else //__WINS__ |
|
883 EnterCriticalSection( &g_IscDTBCriticalSection ); |
|
884 return KErrNone; |
|
885 #endif//__WINS__ |
|
886 } |
|
887 |
|
888 // ----------------------------------------------------------------------------- |
|
889 // DIscDevice::RestoreIrqs |
|
890 // Function to restore interrupts |
|
891 // ( other items were commented in a header ). |
|
892 // ----------------------------------------------------------------------------- |
|
893 // |
|
894 #ifndef __WINS__ |
|
895 void DIscDevice::RestoreIrqs( |
|
896 TInt aLevel ) |
|
897 { |
|
898 NKern::RestoreInterrupts( aLevel ); |
|
899 |
|
900 #else //__WINS__ |
|
901 void DIscDevice::RestoreIrqs( |
|
902 TInt ) |
|
903 { |
|
904 LeaveCriticalSection( &g_IscDTBCriticalSection ); |
|
905 #endif//__WINS__ |
|
906 } |
|
907 |
|
908 |
|
909 // ========================== OTHER EXPORTED FUNCTIONS ========================= |
|
910 |
|
911 // ----------------------------------------------------------------------------- |
|
912 // E32Dll |
|
913 // Epoc Kernel Architecture 2 style entry point |
|
914 // ( other items were commented in a header ). |
|
915 // ----------------------------------------------------------------------------- |
|
916 // |
|
917 DECLARE_STANDARD_LDD() |
|
918 { |
|
919 DLogicalDevice* device = new DIscDevice; |
|
920 if ( !device ) |
|
921 { |
|
922 ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscPanicCreateLogicalDevice ); |
|
923 } |
|
924 return device; |
|
925 } |
|
926 |
|
927 // End of File |