1 /* |
|
2 * Copyright (c) 2006-2007 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: DUN USB plugin |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <c32comm.h> |
|
20 #include <d32usbc.h> |
|
21 #include "DunPlugin.h" |
|
22 #include "DunUtils.h" |
|
23 #include "DunUsbPlugin.h" |
|
24 #include "DunDebug.h" |
|
25 |
|
26 _LIT( KUsbCsyName, "ECACM" ); |
|
27 _LIT( KUsbPortName, "ACM" ); |
|
28 _LIT( KUsbPortPort, "::" ); |
|
29 _LIT( KUsbLddName, "EUSBC" ); |
|
30 _LIT( KUsbChannelName, "DUNUSB::" ); |
|
31 |
|
32 const TInt KCharactersInTInt = 10; // For "2147483648" |
|
33 const TUint8 KDefaultAcmProtocolNum = 0x01; // Hayes compatible modem |
|
34 |
|
35 // ======== MEMBER FUNCTIONS ======== |
|
36 |
|
37 // --------------------------------------------------------------------------- |
|
38 // CDunUsbPlugin::CDunUsbPlugin |
|
39 // --------------------------------------------------------------------------- |
|
40 // |
|
41 CDunUsbPlugin::CDunUsbPlugin() : |
|
42 iServer( NULL ), |
|
43 iUsbListen( NULL ), |
|
44 iUsbConfig( NULL ), |
|
45 iTransporter( NULL ) |
|
46 { |
|
47 } |
|
48 |
|
49 // --------------------------------------------------------------------------- |
|
50 // Destructor. |
|
51 // --------------------------------------------------------------------------- |
|
52 // |
|
53 CDunUsbPlugin::~CDunUsbPlugin() |
|
54 { |
|
55 FTRACE(FPrint( _L( "CDunUsbPlugin::~CDunUsbPlugin()" ) )); |
|
56 Uninitialize(); |
|
57 FTRACE(FPrint( _L( "CDunUsbPlugin::~CDunUsbPlugin() complete" ) )); |
|
58 } |
|
59 |
|
60 // --------------------------------------------------------------------------- |
|
61 // State of this plugin |
|
62 // --------------------------------------------------------------------------- |
|
63 // |
|
64 TDunPluginState CDunUsbPlugin::PluginState() |
|
65 { |
|
66 return iServer->GetPluginStateByUid( KDunUsbPluginUid ); |
|
67 } |
|
68 |
|
69 // --------------------------------------------------------------------------- |
|
70 // Constructs a listener object for this plugin |
|
71 // --------------------------------------------------------------------------- |
|
72 // |
|
73 void CDunUsbPlugin::ConstructListenerL() |
|
74 { |
|
75 FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL()"))); |
|
76 if ( PluginState() != EDunStateLoaded ) |
|
77 { |
|
78 FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL() (not ready) complete"))); |
|
79 User::Leave( KErrNotReady ); |
|
80 } |
|
81 ReportStateChangeUp( EDunStateTryListen ); |
|
82 if ( iUsbListen ) |
|
83 { |
|
84 FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL() (already exists) complete"))); |
|
85 User::Leave( KErrAlreadyExists ); |
|
86 } |
|
87 InitUsbL(); |
|
88 CDunUsbListen* listen = CDunUsbListen::NewL( iServer, this, iUsbServer ); |
|
89 CleanupStack::PushL( listen ); |
|
90 TInt retTemp = listen->IssueRequestL(); |
|
91 CleanupStack::Pop( listen ); |
|
92 iUsbListen = listen; |
|
93 // Here return value of KErrAlreadyExists means the device is already |
|
94 // configured |
|
95 // In this case we have to switch directly to channeled mode |
|
96 ReportStateChangeUp( EDunStateListening ); |
|
97 if ( retTemp == KErrAlreadyExists ) |
|
98 { |
|
99 TBool noFreeChans = EFalse; |
|
100 // noFreeChans will be omitted (not needed to set to RComm) |
|
101 NotifyChannelAllocate( noFreeChans ); // Create channel and change state |
|
102 } |
|
103 FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL() complete"))); |
|
104 } |
|
105 |
|
106 // --------------------------------------------------------------------------- |
|
107 // Initializes USB by loading LDD |
|
108 // --------------------------------------------------------------------------- |
|
109 // |
|
110 void CDunUsbPlugin::InitUsbL() |
|
111 { |
|
112 FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL()") )); |
|
113 // Load Logical device driver for USB |
|
114 FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL() LoadLogicalDevice") )); |
|
115 TInt retTemp = User::LoadLogicalDevice( KUsbLddName ); |
|
116 if ( retTemp!=KErrAlreadyExists && retTemp!=KErrNone ) |
|
117 { |
|
118 User::Leave( retTemp ); |
|
119 } |
|
120 // Connect to the USB Manager server |
|
121 FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL() Connect()") )); |
|
122 User::LeaveIfError( iUsbServer.Connect() ); |
|
123 // Create USB configuration accessor and listener |
|
124 iUsbConfig = CDunUsbConfig::NewL( iServer, this, KDefaultAcmProtocolNum ); |
|
125 FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL() complete") )); |
|
126 } |
|
127 |
|
128 // --------------------------------------------------------------------------- |
|
129 // Initializes all usable USB ports for DUN |
|
130 // --------------------------------------------------------------------------- |
|
131 // |
|
132 TInt CDunUsbPlugin::InitPorts() |
|
133 { |
|
134 FTRACE(FPrint( _L( "CDunUsbPlugin::InitPorts() (num=%d)" ), iUsbPorts.Count())); |
|
135 TInt i; |
|
136 TInt retTemp = CreateAllPorts(); |
|
137 if ( retTemp != KErrNone ) |
|
138 { |
|
139 FTRACE(FPrint( _L( "CDunUsbPlugin::InitPorts() (ERROR) complete" ))); |
|
140 return retTemp; |
|
141 } |
|
142 TInt count = iUsbPorts.Count(); |
|
143 for ( i=0; i<count; i++ ) |
|
144 { |
|
145 retTemp = InitOnePort( &iUsbPorts[i] ); |
|
146 if ( retTemp != KErrNone ) |
|
147 { |
|
148 FTRACE(FPrint( _L( "CDunUsbPlugin::InitPorts() (not ready) complete" ))); |
|
149 return KErrGeneral; |
|
150 } |
|
151 } |
|
152 FTRACE(FPrint( _L( "CDunUsbPlugin::InitPorts() complete" ))); |
|
153 return KErrNone; |
|
154 } |
|
155 |
|
156 // --------------------------------------------------------------------------- |
|
157 // Creates empty usable USB ports that can be used by DUN |
|
158 // --------------------------------------------------------------------------- |
|
159 // |
|
160 TInt CDunUsbPlugin::CreateAllPorts() |
|
161 { |
|
162 FTRACE(FPrint( _L( "CDunUsbPlugin::CreateAllPorts()" ) )); |
|
163 // Connect to comms server |
|
164 TInt retTemp = CDunUtils::ConnectCommsServer( iCommServer ); |
|
165 if ( retTemp != KErrNone ) |
|
166 { |
|
167 FTRACE(FPrint( _L( "CDunUsbPlugin::CreateAllPorts() (ERROR) complete" ))); |
|
168 return retTemp; |
|
169 } |
|
170 // Load communications module |
|
171 retTemp = iCommServer.LoadCommModule( KUsbCsyName ); |
|
172 if ( retTemp!=KErrNone && retTemp!=KErrAlreadyExists ) |
|
173 { |
|
174 FTRACE(FPrint( _L( "CDunUsbPlugin::CreateAllPorts() (LoadCommModule failed) complete" ) )); |
|
175 return retTemp; |
|
176 } |
|
177 // Stop waiter now (just to be sure) before explicitly fetching port data |
|
178 iUsbConfig->Stop(); |
|
179 // Find out what ports can be supported and append them to array |
|
180 TBool validConfig; |
|
181 TUsbPortEntity entity; |
|
182 for ( TInt i=0;; i++ ) |
|
183 { |
|
184 retTemp = iUsbConfig->GetConfigValidityByIndex( i, validConfig ); |
|
185 if ( retTemp != KErrNone ) |
|
186 { |
|
187 break; |
|
188 } |
|
189 if ( !validConfig ) |
|
190 { |
|
191 continue; |
|
192 } |
|
193 // Valid config found, append it to array |
|
194 entity.iPortNum = i; |
|
195 retTemp = iUsbPorts.Append( entity ); |
|
196 if ( retTemp != KErrNone ) |
|
197 { |
|
198 FTRACE(FPrint( _L( "CDunUsbPlugin::CreateAllPorts() (append failed!) complete" ) )); |
|
199 return retTemp; |
|
200 } |
|
201 } |
|
202 FTRACE(FPrint( _L( "CDunUsbPlugin::CreateAllPorts() complete" ) )); |
|
203 return KErrNone; |
|
204 } |
|
205 |
|
206 // --------------------------------------------------------------------------- |
|
207 // Initializes one USB port for DUN |
|
208 // --------------------------------------------------------------------------- |
|
209 // |
|
210 TInt CDunUsbPlugin::InitOnePort( TUsbPortEntity* aEntity ) |
|
211 { |
|
212 FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort()" ))); |
|
213 if ( !aEntity ) |
|
214 { |
|
215 FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() (not initialized!) complete" ))); |
|
216 return KErrGeneral; |
|
217 } |
|
218 TInt retTemp; |
|
219 TName portName; |
|
220 portName.Copy( KUsbPortName ); |
|
221 portName.Append( KUsbPortPort ); |
|
222 portName.AppendNum( aEntity->iPortNum ); |
|
223 retTemp = aEntity->iUsbPort.Open( iCommServer, |
|
224 portName, |
|
225 ECommExclusive, |
|
226 ECommRoleDCE ); |
|
227 if ( retTemp != KErrNone ) |
|
228 { |
|
229 FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() Open failed (%d)" ), retTemp)); |
|
230 return retTemp; |
|
231 } |
|
232 TRAPD( retTrap, SetChannelL(aEntity) ); |
|
233 if ( retTrap != KErrNone ) |
|
234 { |
|
235 iTransporter->FreeChannel( &aEntity->iUsbPort ); |
|
236 FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() (trapped!) complete" ))); |
|
237 return retTrap; |
|
238 } |
|
239 FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() complete" ))); |
|
240 return KErrNone; |
|
241 } |
|
242 |
|
243 // --------------------------------------------------------------------------- |
|
244 // Sets channel for one USB port |
|
245 // --------------------------------------------------------------------------- |
|
246 // |
|
247 void CDunUsbPlugin::SetChannelL( TUsbPortEntity* aEntity ) |
|
248 { |
|
249 FTRACE(FPrint( _L( "CDunUsbPlugin::SetChannelL()" ))); |
|
250 if ( !aEntity ) |
|
251 { |
|
252 FTRACE(FPrint( _L( "CDunUsbPlugin::SetChannelL() (not initialized!) complete" ))); |
|
253 User::Leave( KErrGeneral ); |
|
254 } |
|
255 HBufC8* channelName = HBufC8::NewMaxLC( KUsbChannelName().Length() + |
|
256 KCharactersInTInt ); |
|
257 TPtr8 channelNamePtr = channelName->Des(); |
|
258 channelNamePtr.Copy( KUsbChannelName ); |
|
259 channelNamePtr.AppendNum( aEntity->iPortNum ); |
|
260 iTransporter->AllocateChannelL( &aEntity->iUsbPort, |
|
261 KDunUsbPluginUid, |
|
262 channelNamePtr, |
|
263 ETrue, |
|
264 this ); |
|
265 AddSkippedErrorL( KErrUsbInterfaceChange, &aEntity->iUsbPort ); |
|
266 iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, |
|
267 this, |
|
268 EDunReaderUpstream, |
|
269 EFalse ); |
|
270 iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, |
|
271 this, |
|
272 EDunWriterUpstream, |
|
273 EFalse ); |
|
274 iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, |
|
275 this, |
|
276 EDunReaderDownstream, |
|
277 EFalse ); |
|
278 iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, |
|
279 this, |
|
280 EDunWriterDownstream, |
|
281 EFalse ); |
|
282 iTransporter->IssueTransferRequestsL( &aEntity->iUsbPort ); |
|
283 CleanupStack::PopAndDestroy( channelName ); |
|
284 FTRACE(FPrint( _L( "CDunUsbPlugin::SetChannelL() complete" ))); |
|
285 } |
|
286 |
|
287 // --------------------------------------------------------------------------- |
|
288 // Adds skipped error code to Transporter |
|
289 // The skipped error is added to local media's read and write operations |
|
290 // --------------------------------------------------------------------------- |
|
291 // |
|
292 void CDunUsbPlugin::AddSkippedErrorL( TInt aError, RComm* aComm ) |
|
293 { |
|
294 iTransporter->AddSkippedErrorL( aError, aComm, EDunReaderUpstream ); |
|
295 iTransporter->AddSkippedErrorL( aError, aComm, EDunWriterDownstream ); |
|
296 } |
|
297 |
|
298 // --------------------------------------------------------------------------- |
|
299 // Sets new state |
|
300 // New state must be one more than the old state |
|
301 // --------------------------------------------------------------------------- |
|
302 // |
|
303 TInt CDunUsbPlugin::ReportStateChangeUp( TDunPluginState aPluginState ) |
|
304 { |
|
305 FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeUp()"))); |
|
306 TInt retTemp = iServer->NotifyPluginStateChangeUp( aPluginState, |
|
307 KDunUsbPluginUid ); |
|
308 if ( retTemp != KErrNone ) |
|
309 { |
|
310 FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeUp() (ERROR) complete"))); |
|
311 return retTemp; |
|
312 } |
|
313 FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeUp() complete"))); |
|
314 return KErrNone; |
|
315 } |
|
316 |
|
317 // --------------------------------------------------------------------------- |
|
318 // Sets new state |
|
319 // New state must be one less than the old state |
|
320 // --------------------------------------------------------------------------- |
|
321 // |
|
322 TInt CDunUsbPlugin::ReportStateChangeDown( TDunPluginState aPluginState ) |
|
323 { |
|
324 FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeDown()"))); |
|
325 TInt retTemp = iServer->NotifyPluginStateChangeDown( aPluginState, |
|
326 KDunUsbPluginUid ); |
|
327 if ( retTemp != KErrNone ) |
|
328 { |
|
329 FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeDown() (ERROR) complete"))); |
|
330 return retTemp; |
|
331 } |
|
332 FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeDown() complete"))); |
|
333 return KErrNone; |
|
334 } |
|
335 |
|
336 // --------------------------------------------------------------------------- |
|
337 // Frees existing channels |
|
338 // --------------------------------------------------------------------------- |
|
339 // |
|
340 TInt CDunUsbPlugin::FreeChannels() |
|
341 { |
|
342 FTRACE(FPrint(_L("CDunUsbPlugin::FreeChannels()"))); |
|
343 if ( PluginState() != EDunStateTryUninitialize ) |
|
344 { |
|
345 FTRACE(FPrint( _L( "CDunUsbPlugin::FreeChannels() (not ready) complete" ) )); |
|
346 return KErrNotReady; |
|
347 } |
|
348 TInt i; |
|
349 TInt count = iUsbPorts.Count(); |
|
350 for ( i=0; i<count; i++ ) |
|
351 { |
|
352 FTRACE(FPrint( _L( "CDunUsbPlugin::FreeChannels() i=%d" ), i)); |
|
353 if ( iUsbPorts[i].iUsbPort.SubSessionHandle() ) |
|
354 { |
|
355 iTransporter->FreeChannel( &iUsbPorts[i].iUsbPort ); |
|
356 iUsbPorts[i].iUsbPort.SetSignals( 0, KSignalDCEOutputs ); |
|
357 iUsbPorts[i].iUsbPort.Close(); |
|
358 } |
|
359 } |
|
360 iUsbPorts.Close(); |
|
361 if ( iCommServer.Handle() != KNullHandle ) |
|
362 { |
|
363 iCommServer.UnloadCommModule( KUsbCsyName ); |
|
364 iCommServer.Close(); |
|
365 } |
|
366 FTRACE(FPrint(_L("CDunUsbPlugin::FreeChannels() complete"))); |
|
367 return KErrNone; |
|
368 } |
|
369 |
|
370 // --------------------------------------------------------------------------- |
|
371 // Uninitializes this plugin |
|
372 // --------------------------------------------------------------------------- |
|
373 // |
|
374 TInt CDunUsbPlugin::Uninitialize() |
|
375 { |
|
376 FTRACE(FPrint( _L( "CDunUsbPlugin::Uninitialize()" ) )); |
|
377 ReportStateChangeDown( EDunStateTryUninitialize ); |
|
378 // Free channel(s), ignore errors |
|
379 FreeChannels(); |
|
380 delete iUsbListen; // delete before iUsbServer close |
|
381 iUsbListen = NULL; |
|
382 delete iUsbConfig; |
|
383 iUsbConfig = NULL; |
|
384 if ( iUsbServer.Handle() != KNullHandle ) |
|
385 { |
|
386 iUsbServer.Close(); |
|
387 } |
|
388 User::FreeLogicalDevice( KUsbLddName ); |
|
389 ReportStateChangeUp( EDunStateUninitialized ); |
|
390 ReportStateChangeUp( EDunStateTryLoad ); |
|
391 ReportStateChangeUp( EDunStateLoaded ); |
|
392 FTRACE(FPrint( _L( "CDunUsbPlugin::Uninitialize() complete" ) )); |
|
393 return KErrNone; |
|
394 } |
|
395 |
|
396 // --------------------------------------------------------------------------- |
|
397 // Gets port's index and entity by connection ID |
|
398 // --------------------------------------------------------------------------- |
|
399 // |
|
400 TInt CDunUsbPlugin::GetEntityByConnId( TConnId aConnId, |
|
401 TUsbPortEntity*& aEntity ) |
|
402 { |
|
403 FTRACE(FPrint( _L( "CDunUsbPlugin::GetEntityByConnId()")) ); |
|
404 TInt i; |
|
405 TInt count = iUsbPorts.Count(); |
|
406 for ( i=0; i<count; i++ ) |
|
407 { |
|
408 if ( &iUsbPorts[i].iUsbPort == aConnId ) |
|
409 { |
|
410 aEntity = &iUsbPorts[i]; |
|
411 FTRACE(FPrint( _L( "CDunUsbPlugin::GetEntityByConnId() complete")) ); |
|
412 return i; |
|
413 } |
|
414 } |
|
415 aEntity = NULL; |
|
416 FTRACE(FPrint( _L( "CDunUsbPlugin::GetEntityByConnId() (not found) complete")) ); |
|
417 return KErrNotFound; |
|
418 } |
|
419 |
|
420 // --------------------------------------------------------------------------- |
|
421 // Gets port's entity by port number |
|
422 // --------------------------------------------------------------------------- |
|
423 // |
|
424 TInt CDunUsbPlugin::GetEntityByPortNumber( TInt aPortNum, |
|
425 TUsbPortEntity*& aEntity ) |
|
426 { |
|
427 FTRACE(FPrint( _L( "CDunUsbPlugin::GetEntityByPortNumber()")) ); |
|
428 TInt i; |
|
429 TInt count = iUsbPorts.Count(); |
|
430 for ( i=0; i<count; i++ ) |
|
431 { |
|
432 if ( iUsbPorts[i].iPortNum == aPortNum ) |
|
433 { |
|
434 aEntity = &iUsbPorts[i]; |
|
435 FTRACE(FPrint( _L( "CDunUsbPlugin::GetEntityByPortNumber() complete")) ); |
|
436 return i; |
|
437 } |
|
438 } |
|
439 aEntity = NULL; |
|
440 FTRACE(FPrint( _L( "CDunUsbPlugin::GetEntityByPortNumber() (not found) complete")) ); |
|
441 return KErrNotFound; |
|
442 } |
|
443 |
|
444 // --------------------------------------------------------------------------- |
|
445 // Gets first free port's index and entity |
|
446 // --------------------------------------------------------------------------- |
|
447 // |
|
448 TInt CDunUsbPlugin::GetFirstFreeEntity( TUsbPortEntity*& aEntity ) |
|
449 { |
|
450 FTRACE(FPrint( _L( "CDunUsbPlugin::GetFirstFreeEntity()")) ); |
|
451 TInt i; |
|
452 TInt count = iUsbPorts.Count(); |
|
453 for ( i=0; i<count; i++ ) |
|
454 { |
|
455 if ( iUsbPorts[i].iPortNum == KErrNotFound && |
|
456 !iUsbPorts[i].iUsbPort.SubSessionHandle() ) |
|
457 { |
|
458 aEntity = &iUsbPorts[i]; |
|
459 FTRACE(FPrint( _L( "CDunUsbPlugin::GetFirstFreeEntity() complete")) ); |
|
460 return i; |
|
461 } |
|
462 } |
|
463 aEntity = NULL; |
|
464 FTRACE(FPrint( _L( "CDunUsbPlugin::GetFirstFreeEntity() (not found) complete")) ); |
|
465 return KErrNotFound; |
|
466 } |
|
467 |
|
468 // --------------------------------------------------------------------------- |
|
469 // From class MDunLocalMediaPlugin. |
|
470 // CDunUsbPlugin::ConstructL |
|
471 // --------------------------------------------------------------------------- |
|
472 // |
|
473 void CDunUsbPlugin::ConstructL( MDunServerCallback* aServer, |
|
474 CDunTransporter* aTransporter ) |
|
475 { |
|
476 FTRACE(FPrint( _L( "CDunUsbPlugin::ConstructL()" ) )); |
|
477 if ( !aServer || !aTransporter ) |
|
478 { |
|
479 FTRACE(FPrint( _L( "CDunUsbPlugin::ConstructL() not initialized!" ) )); |
|
480 User::Leave( KErrGeneral ); |
|
481 } |
|
482 iServer = aServer; |
|
483 iTransporter = aTransporter; |
|
484 FTRACE(FPrint( _L( "CDunUsbPlugin::ConstructL() complete" ) )); |
|
485 } |
|
486 |
|
487 // --------------------------------------------------------------------------- |
|
488 // From class MDunLocalMediaPlugin. |
|
489 // Gets called when server changes a plugin's state |
|
490 // --------------------------------------------------------------------------- |
|
491 // |
|
492 TInt CDunUsbPlugin::NotifyServerStateChange( TDunPluginState aPluginState ) |
|
493 { |
|
494 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyServerStateChange()"))); |
|
495 TInt retTemp; |
|
496 switch ( aPluginState ) |
|
497 { |
|
498 case EDunStateTryListen: |
|
499 if ( PluginState() != EDunStateLoaded ) |
|
500 { |
|
501 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyServerStateChange() (not ready) complete"))); |
|
502 return KErrNotReady; |
|
503 } |
|
504 // Change to listening mode |
|
505 TRAPD( retTrap, ConstructListenerL() ); |
|
506 if ( retTrap != KErrNone ) |
|
507 { |
|
508 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyServerStateChange() (ERROR) complete (%d)"), retTrap)); |
|
509 return retTrap; |
|
510 } |
|
511 break; |
|
512 case EDunStateTryUninitialize: |
|
513 if ( PluginState() == EDunStateUninitialized ) |
|
514 { |
|
515 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyServerStateChange() (not ready) complete"))); |
|
516 return KErrNotReady; |
|
517 } |
|
518 // Uninitialize |
|
519 retTemp = Uninitialize(); |
|
520 if ( retTemp != KErrNone ) |
|
521 { |
|
522 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyServerStateChange() (not ready) complete (%d)"), retTemp)); |
|
523 return retTemp; |
|
524 } |
|
525 break; |
|
526 default: |
|
527 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyServerStateChange() (unknown state) complete"))); |
|
528 return KErrNotSupported; |
|
529 } |
|
530 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyServerStateChange() complete"))); |
|
531 return KErrNone; |
|
532 } |
|
533 |
|
534 // --------------------------------------------------------------------------- |
|
535 // From class MDunLocalMediaPlugin. |
|
536 // Gets called when server needs to know the active connection |
|
537 // --------------------------------------------------------------------------- |
|
538 // |
|
539 TConnId CDunUsbPlugin::ActiveConnection() |
|
540 { |
|
541 FTRACE(FPrint(_L("CDunUsbPlugin::ActiveConnection()"))); |
|
542 FTRACE(FPrint(_L("CDunUsbPlugin::ActiveConnection() (not found) complete"))); |
|
543 return NULL; |
|
544 } |
|
545 |
|
546 // --------------------------------------------------------------------------- |
|
547 // From class MDunListenCallback. |
|
548 // Gets called when new channel must be created |
|
549 // --------------------------------------------------------------------------- |
|
550 // |
|
551 TInt CDunUsbPlugin::NotifyChannelAllocate( TBool& /*aNoFreeChans*/ ) |
|
552 { |
|
553 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelAllocate()"))); |
|
554 if ( PluginState() != EDunStateListening ) |
|
555 { |
|
556 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelAllocate() (not ready) complete"))); |
|
557 return KErrNotReady; |
|
558 } |
|
559 ReportStateChangeUp( EDunStateTryChannel ); |
|
560 TInt retTemp = InitPorts(); |
|
561 if ( retTemp != KErrNone ) |
|
562 { |
|
563 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelAllocate() (ERROR) complete"))); |
|
564 return retTemp; |
|
565 } |
|
566 // Channels allocated so start to wait for possible port config change |
|
567 retTemp = iUsbConfig->IssueRequest(); |
|
568 if ( retTemp != KErrNone ) |
|
569 { |
|
570 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelAllocate() (ERROR) complete"))); |
|
571 return retTemp; |
|
572 } |
|
573 iShutdown = EFalse; |
|
574 ReportStateChangeUp( EDunStateChanneled ); |
|
575 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelAllocate() complete"))); |
|
576 return KErrNone; |
|
577 } |
|
578 |
|
579 // --------------------------------------------------------------------------- |
|
580 // From class MDunListenCallback. |
|
581 // Gets called when an existing channel must be freed |
|
582 // --------------------------------------------------------------------------- |
|
583 // |
|
584 TInt CDunUsbPlugin::NotifyChannelFree() |
|
585 { |
|
586 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree()"))); |
|
587 if ( PluginState() != EDunStateChanneled ) |
|
588 { |
|
589 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree() (not ready) complete"))); |
|
590 return KErrNotReady; |
|
591 } |
|
592 // Cable removed or PC sleep, hibernate or reset. |
|
593 // Just remove channels. |
|
594 ReportStateChangeDown( EDunStateTryUninitialize ); |
|
595 TInt retTemp = FreeChannels(); |
|
596 if ( retTemp != KErrNone ) |
|
597 { |
|
598 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree() (ERROR) complete"))); |
|
599 return retTemp; |
|
600 } |
|
601 ReportStateChangeUp( EDunStateUninitialized ); |
|
602 ReportStateChangeUp( EDunStateTryLoad ); |
|
603 ReportStateChangeUp( EDunStateLoaded ); |
|
604 ReportStateChangeUp( EDunStateTryListen ); |
|
605 ReportStateChangeUp( EDunStateListening ); |
|
606 FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree() complete"))); |
|
607 return KErrNone; |
|
608 } |
|
609 |
|
610 // --------------------------------------------------------------------------- |
|
611 // From class MDunConnMon. |
|
612 // Gets called when line status changes or when any type of error is detected |
|
613 // --------------------------------------------------------------------------- |
|
614 // |
|
615 void CDunUsbPlugin::NotifyProgressChangeL( |
|
616 TConnId aConnId, |
|
617 TDunConnectionReason aConnReason ) |
|
618 { |
|
619 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL()")) ); |
|
620 // Find matching failed ID |
|
621 TUsbPortEntity* foundEntity = NULL; |
|
622 TInt foundIndex = GetEntityByConnId( aConnId, foundEntity ); |
|
623 if ( !foundEntity ) |
|
624 { |
|
625 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() (not found) complete")) ); |
|
626 User::Leave( KErrNotFound ); |
|
627 } |
|
628 if ( aConnReason.iReasonType == EDunReasonTypeRW || |
|
629 aConnReason.iReasonType == EDunReasonTypeRunL ) |
|
630 { |
|
631 // The following check will make it possible for CDunUsbListen to react |
|
632 // to cable removal (<KErrUsbDriverBase) or to the case when personality |
|
633 // is changed from USBUI and LOCOD/USBWatcher is too slow to notify the |
|
634 // change (KErrAccessDenied). |
|
635 if ( aConnReason.iErrorCode < KErrUsbDriverBase || |
|
636 aConnReason.iErrorCode == KErrAccessDenied ) |
|
637 { |
|
638 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() (shutdown now) complete")) ); |
|
639 iShutdown = ETrue; |
|
640 return; |
|
641 } |
|
642 } |
|
643 if ( iShutdown ) |
|
644 { |
|
645 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() (shutdown) complete")) ); |
|
646 return; |
|
647 } |
|
648 // Now indications are down indications from local media side |
|
649 if ( foundEntity->iUsbPort.SubSessionHandle() ) |
|
650 { |
|
651 iTransporter->FreeChannel( &foundEntity->iUsbPort ); |
|
652 foundEntity->iUsbPort.SetSignals( 0, KSignalDCEOutputs ); |
|
653 foundEntity->iUsbPort.Close(); |
|
654 } |
|
655 TInt retTemp = InitOnePort( foundEntity ); |
|
656 if ( retTemp != KErrNone ) |
|
657 { |
|
658 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() (ERROR) complete")) ); |
|
659 User::Leave( KErrGeneral ); |
|
660 } |
|
661 // Now this plugin was basically "restarted", but only for one |
|
662 // channel. Because transporter has channels with waiters, notify |
|
663 // server to reopen queued plugin(s) |
|
664 iServer->NotifyPluginReopenRequest(); |
|
665 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() complete")) ); |
|
666 } |
|
667 |
|
668 // --------------------------------------------------------------------------- |
|
669 // From class MDunBufferCorrection. |
|
670 // Gets called when request to change local media's buffer size |
|
671 // --------------------------------------------------------------------------- |
|
672 // |
|
673 TInt CDunUsbPlugin::NotifyBufferCorrection( TInt aLength ) |
|
674 { |
|
675 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyBufferCorrection()")) ); |
|
676 /* |
|
677 * This method modifies the default buffer length to match the maximum value |
|
678 * used by "CanHandleZLP=0" configuration option. This length is nearest length |
|
679 * divisible by 64 - 1. With slow USB compared to high speed HSDPA some products |
|
680 * can start to collect data to Dataport which results in full packet writes to |
|
681 * USB. However, the default full packet must not be divisible by 64, which results |
|
682 * in the ACM to send the full packet to LDD plus one extra packet with one byte |
|
683 * (disabling interrupts for a long time with current non-DMA USB driver). |
|
684 */ |
|
685 TInt newLength = aLength; |
|
686 if ( newLength % 64 == 0 ) |
|
687 { |
|
688 newLength = ((aLength >> 6) << 6) - 1; |
|
689 } |
|
690 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyBufferCorrection() complete")) ); |
|
691 return newLength; |
|
692 } |
|
693 |
|
694 // --------------------------------------------------------------------------- |
|
695 // From class MDunUsbConfig. |
|
696 // Gets called when one or more ACM configurations are added |
|
697 // --------------------------------------------------------------------------- |
|
698 // |
|
699 TInt CDunUsbPlugin::NotifyConfigAddition( TInt aIndex ) |
|
700 { |
|
701 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition()")) ); |
|
702 // Configuration added so aIndex is the port number to be added to array. |
|
703 // This port number must not already exist in the array. |
|
704 TUsbPortEntity* foundEntity = NULL; |
|
705 TInt foundIndex = GetEntityByPortNumber( aIndex, foundEntity ); |
|
706 if ( foundEntity ) |
|
707 { |
|
708 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() (already exists) complete")) ); |
|
709 return KErrAlreadyExists; |
|
710 } |
|
711 // Now either find port with KErrNotFound set as port number or if that is |
|
712 // not found then try to append to array |
|
713 foundIndex = GetFirstFreeEntity( foundEntity ); |
|
714 if ( !foundEntity ) // free not found so add new |
|
715 { |
|
716 // Now append the new port to array |
|
717 TUsbPortEntity newEntity; |
|
718 newEntity.iPortNum = aIndex; |
|
719 TInt retTemp = iUsbPorts.Append( newEntity ); |
|
720 if ( retTemp != KErrNone ) |
|
721 { |
|
722 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() (append failed!) complete")) ); |
|
723 return KErrGeneral; |
|
724 } |
|
725 // entity not valid here so set now |
|
726 foundEntity = &iUsbPorts[iUsbPorts.Count()-1]; |
|
727 } |
|
728 else // free found so change array |
|
729 { |
|
730 foundEntity->iPortNum = aIndex; |
|
731 } |
|
732 // Open port and create channel for it |
|
733 TInt retTemp = InitOnePort( foundEntity ); |
|
734 if ( retTemp != KErrNone ) |
|
735 { |
|
736 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() (ERROR) complete" ))); |
|
737 return KErrGeneral; |
|
738 } |
|
739 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() complete")) ); |
|
740 return KErrNone; |
|
741 } |
|
742 |
|
743 // --------------------------------------------------------------------------- |
|
744 // From class MDunUsbConfig. |
|
745 // Gets called when one or more ACM configurations are removed |
|
746 // --------------------------------------------------------------------------- |
|
747 // |
|
748 TInt CDunUsbPlugin::NotifyConfigRemoval( TInt aIndex ) |
|
749 { |
|
750 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigRemoval()")) ); |
|
751 // Configuration removed so aIndex is the port number to be added to array. |
|
752 // This port number must already exist in the array. |
|
753 TUsbPortEntity* foundEntity = NULL; |
|
754 TInt foundIndex = GetEntityByPortNumber( aIndex, foundEntity ); |
|
755 if ( !foundEntity ) |
|
756 { |
|
757 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigRemoval() (not found) complete")) ); |
|
758 return KErrNotFound; |
|
759 } |
|
760 // Now free channel and mark as unused |
|
761 iTransporter->FreeChannel( &foundEntity->iUsbPort ); |
|
762 foundEntity->iUsbPort.SetSignals( 0, KSignalDCEOutputs ); |
|
763 foundEntity->iUsbPort.Close(); |
|
764 iUsbPorts[foundIndex].iPortNum = KErrNotFound; |
|
765 FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigRemoval() complete")) ); |
|
766 return KErrNone; |
|
767 } |
|
768 |
|
769 // ======== GLOBAL FUNCTIONS ======== |
|
770 |
|
771 // --------------------------------------------------------------------------- |
|
772 // NewLocalPluginL implements factory construction for |
|
773 // the class CDunUsbPlugin. |
|
774 // The function is exported at ordinal 1. |
|
775 // Returns: Pointer: The new instance of CDunUsbPlugin |
|
776 // --------------------------------------------------------------------------- |
|
777 // |
|
778 EXPORT_C MDunLocalMediaPlugin* NewLocalPluginL() |
|
779 { |
|
780 return new (ELeave) CDunUsbPlugin; |
|
781 } |
|