|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * Source file for USB Phonet Link starter. |
|
16 */ |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include "usbpnstarter.h" // For trace macros |
|
20 #include <rusbpnclient.h> // For RUsbPnClient |
|
21 #include <e32std.h> // For User |
|
22 #include <d32usbc.h> // For RDevUsbcClient |
|
23 #ifdef BSW_USB_DRC // flag for OTG support |
|
24 #include <d32otgdi.h> // RUsbOtgDriver |
|
25 #endif // BSW_USB_DRC |
|
26 |
|
27 |
|
28 // EXTERNAL DATA STRUCTURES |
|
29 // EXTERNAL FUNCTION PROTOTYPES |
|
30 // CONSTANTS |
|
31 _LIT(KUsbLDDName, "eusbc"); |
|
32 #ifdef BSW_USB_DRC |
|
33 _LIT(KOtgdiLddFilename, "otgdi"); |
|
34 #endif // BSW_USB_DRC |
|
35 |
|
36 //Device Descriptor Offsets |
|
37 const TInt KUsbSpecOffset = 2; |
|
38 const TInt KUsbDeviceClassOffset = 4; |
|
39 const TInt KUsbDeviceSubClassOffset = 5; |
|
40 const TInt KUsbDeviceProtocolOffset = 6; |
|
41 const TInt KUsbVendorIdOffset = 8; |
|
42 const TInt KUsbProductIdOffset = 10; |
|
43 const TInt KUsbDevReleaseOffset = 12; |
|
44 |
|
45 // MACROS |
|
46 // LOCAL CONSTANTS AND MACROS |
|
47 // MODULE DATA STRUCTURES |
|
48 // LOCAL FUNCTION PROTOTYPES |
|
49 // FORWARD DECLARATIONS |
|
50 |
|
51 // ============================= LOCAL FUNCTIONS =============================== |
|
52 // ----------------------------------------------------------------------------- |
|
53 // LoadUsbDriverL() |
|
54 // ----------------------------------------------------------------------------- |
|
55 void LoadUsbDriverL( RDevUsbcClient& aDriver ) |
|
56 { |
|
57 C_TRACE( ( _T("usbpnstarter # LoadUsbDriverL") ) ); |
|
58 |
|
59 TInt error = User::LoadLogicalDevice(KUsbLDDName); |
|
60 if( error != KErrNone || error != KErrAlreadyExists ) |
|
61 { |
|
62 C_TRACE( ( _T("usbpnstarter # LoadUsbDriverL - LDD load failed: %d"), error ) ); |
|
63 User::Leave(error); |
|
64 } |
|
65 // Open channel to device driver. |
|
66 error = aDriver.Open(0); |
|
67 if ( error != KErrNone ) |
|
68 { |
|
69 C_TRACE( ( _T("usbpnstarter # LoadUsbDriverL - aDriver.Open failed: %d"), error ) ); |
|
70 User::Leave(error); |
|
71 } |
|
72 #ifdef BSW_USB_DRC |
|
73 error = User::LoadLogicalDevice(KOtgdiLddFilename); |
|
74 if( error != KErrNone && error != KErrAlreadyExists ) |
|
75 { |
|
76 C_TRACE( ( _T("usbpnstarter # Error %d on loading OTG LDD"), error ) ); |
|
77 User::Leave(error); |
|
78 } |
|
79 RUsbOtgDriver otgDevice; |
|
80 error = otgDevice.Open(); |
|
81 if (error != KErrNone) |
|
82 { |
|
83 C_TRACE( ( _T("usbpnstarter # Error %d on opening OTG port"), error ) ); |
|
84 User::Leave(error); |
|
85 } |
|
86 error = otgDevice.StartStacks(); |
|
87 if (error != KErrNone) |
|
88 { |
|
89 C_TRACE( ( _T("usbpnstarter # Error %d on starting USB stack"), error ) ); |
|
90 User::Leave(error); |
|
91 } |
|
92 #endif // BSW_USB_DRC |
|
93 } |
|
94 // ----------------------------------------------------------------------------- |
|
95 // SetupDeviceDescriptors() |
|
96 // ----------------------------------------------------------------------------- |
|
97 TInt SetupDeviceDescriptors( RDevUsbcClient& aDriver ) |
|
98 { |
|
99 C_TRACE( ( _T( "usbpnstarter # SetupDeviceDescriptors") ) ); |
|
100 // Simulates a physical removal of the USB cable |
|
101 TInt ret = aDriver.DeviceDisconnectFromHost(); |
|
102 |
|
103 TBuf8<KUsbDescSize_Device> deviceDescriptor; |
|
104 ret = aDriver.GetDeviceDescriptor( deviceDescriptor ); |
|
105 if( ret != KErrNone ) |
|
106 { |
|
107 return KErrGeneral; |
|
108 } |
|
109 |
|
110 // Change the USB spec number to 2.00 |
|
111 deviceDescriptor[ KUsbSpecOffset ] = 0x00; |
|
112 deviceDescriptor[ KUsbSpecOffset+1 ] = 0x02; |
|
113 |
|
114 //Change the Device Class Codes |
|
115 deviceDescriptor[ KUsbDeviceClassOffset ] = 0x02; // Class = 0x02; |
|
116 deviceDescriptor[ KUsbDeviceSubClassOffset ] = 0x00; // SubClass = 0x00; |
|
117 deviceDescriptor[ KUsbDeviceProtocolOffset ] = 0x00; // Protocol = 0x00; |
|
118 |
|
119 // Change the device vendor ID ( VID ) to 0x0421 ( Nokia Vendor ID ) |
|
120 deviceDescriptor[ KUsbVendorIdOffset ] = 0x21; |
|
121 deviceDescriptor[ KUsbVendorIdOffset+1 ] = 0x04; |
|
122 |
|
123 // Change the device product ID ( PID )( Generic Nokia ID ) to 0x00c8 |
|
124 deviceDescriptor[ KUsbProductIdOffset ] = 0xC8; |
|
125 deviceDescriptor[ KUsbProductIdOffset+1 ] = 0x00; |
|
126 |
|
127 // Change the device release number to 0x0110 |
|
128 deviceDescriptor[ KUsbDevReleaseOffset ] = 0x10; |
|
129 deviceDescriptor[ KUsbDevReleaseOffset+1 ] = 0x01; |
|
130 |
|
131 ret = aDriver.SetDeviceDescriptor( deviceDescriptor ); |
|
132 if( ret != KErrNone ) |
|
133 { |
|
134 return KErrGeneral; |
|
135 } |
|
136 |
|
137 C_TRACE( ( _T( "usbpnstarter # SetupDeviceDescriptors return %d"), ret) ); |
|
138 return ret; |
|
139 } |
|
140 // ----------------------------------------------------------------------------- |
|
141 // CreateGenericCdcInterface() |
|
142 // ----------------------------------------------------------------------------- |
|
143 TInt CreateGenericCdcInterface( RDevUsbcClient& aDriver ) |
|
144 { |
|
145 C_TRACE( ( _T( "usbpnstarter # CreateGenericCdcInterface()") ) ); |
|
146 TInt ret = KErrNone; |
|
147 |
|
148 TUsbDeviceCaps deviceCaps; |
|
149 ret = aDriver.DeviceCaps(deviceCaps); |
|
150 |
|
151 if ( KErrNone == ret ) |
|
152 { |
|
153 TInt totalEndpoints = deviceCaps().iTotalEndpoints; |
|
154 |
|
155 C_TRACE( ( _T( "usbpnstarter # CreateGenericCdcInterface Number of endpoints: %d"), totalEndpoints) ); |
|
156 |
|
157 // Endpoints |
|
158 TUsbcEndpointData data[KUsbcMaxEndpoints]; |
|
159 TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data)); |
|
160 ret = aDriver.EndpointCaps(dataptr); |
|
161 if ( KErrNone == ret ) |
|
162 { |
|
163 TUsbcInterfaceInfoBuf ifc; |
|
164 TInt endPointsFound = 0; |
|
165 TBool foundBulkIN = EFalse; |
|
166 TBool foundBulkOUT = EFalse; |
|
167 TInt i = 0; |
|
168 ret = KErrNotFound; |
|
169 while ( i < totalEndpoints && endPointsFound < 2 ) |
|
170 { |
|
171 const TUsbcEndpointCaps* caps = &data[i].iCaps; |
|
172 const TInt maxPacketSize = caps->MaxPacketSize(); |
|
173 if ( !foundBulkIN && |
|
174 (caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) == (KUsbEpTypeBulk | KUsbEpDirIn) ) |
|
175 { |
|
176 C_TRACE( ( _T( "usbpnstarter # CreateGenericCdcInterface EEndpoint%d is going to be our TX (IN, write) endpoint"), i) ); |
|
177 // EEndpoint1 is going to be our TX (IN, write) endpoint |
|
178 ifc().iEndpointData[0].iType = KUsbEpTypeBulk; |
|
179 ifc().iEndpointData[0].iDir = KUsbEpDirIn; |
|
180 ifc().iEndpointData[0].iSize = maxPacketSize; |
|
181 foundBulkIN = ETrue; |
|
182 endPointsFound++; |
|
183 } |
|
184 if ( !foundBulkOUT && |
|
185 (caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) == (KUsbEpTypeBulk | KUsbEpDirOut) ) |
|
186 { |
|
187 C_TRACE( ( _T( "usbpnstarter # CreateGenericCdcInterface EEndpoint%d is going to be our RX (OUT, read) endpoint"), i) ); |
|
188 // EEndpoint2 is going to be our RX (OUT, read) endpoint |
|
189 ifc().iEndpointData[1].iType = KUsbEpTypeBulk; |
|
190 ifc().iEndpointData[1].iDir = KUsbEpDirOut; |
|
191 ifc().iEndpointData[1].iSize = maxPacketSize; |
|
192 foundBulkOUT = ETrue; |
|
193 endPointsFound++; |
|
194 } |
|
195 i++; |
|
196 } |
|
197 |
|
198 if ( endPointsFound == 2 ) |
|
199 { |
|
200 _LIT16(KUSBName, "HS USB Test Interface"); |
|
201 |
|
202 TBufC16<30> string(KUSBName); |
|
203 ifc().iString = &string; |
|
204 ifc().iTotalEndpointsUsed = 2; |
|
205 ifc().iClass.iClassNum = 0xff; |
|
206 ifc().iClass.iSubClassNum = 0xff; |
|
207 ifc().iClass.iProtocolNum = 0xff; |
|
208 |
|
209 ret = aDriver.SetInterface(0, ifc); |
|
210 } |
|
211 } |
|
212 } |
|
213 |
|
214 C_TRACE( ( _T( "usbpnstarter # CreateGenericCdcInterface return %d"), ret) ); |
|
215 return ret; |
|
216 } |
|
217 // ============================ MEMBER FUNCTIONS =============================== |
|
218 // ========================== OTHER EXPORTED FUNCTIONS ========================= |
|
219 |
|
220 // ----------------------------------------------------------------------------- |
|
221 // E32Main() |
|
222 // ----------------------------------------------------------------------------- |
|
223 GLDEF_C TInt E32Main() |
|
224 { |
|
225 C_TRACE( ( _T( "usbpnstarter # E32Main()") ) ); |
|
226 RDevUsbcClient usbDriver; |
|
227 TRAPD( ret, LoadUsbDriverL( usbDriver ) ); |
|
228 if( ret != KErrNone ) |
|
229 { |
|
230 C_TRACE( ( _T( "usbpnstarter # E32Main() - LoadUsbDriverL failed.") ) ); |
|
231 return ret; |
|
232 } |
|
233 ret = SetupDeviceDescriptors( usbDriver ); |
|
234 if( ret != KErrNone ) |
|
235 { |
|
236 C_TRACE( ( _T( "usbpnstarter # E32Main() - SetupDeviceDescriptors failed.") ) ); |
|
237 return ret; |
|
238 } |
|
239 |
|
240 RUsbPnClient usbPnClient; |
|
241 TRAPD( ret, usbPnClient.ConnectL() ); |
|
242 if ( ret != KErrNone ) |
|
243 { |
|
244 C_TRACE( ( _T( "usbpnstarter # E32Main() - ConnectL failed.") ) ); |
|
245 return ret; |
|
246 } |
|
247 usbDriver.PowerUpUdc(); |
|
248 usbDriver.DeviceConnectToHost(); |
|
249 |
|
250 ret = CreateGenericCdcInterface( usbDriver ); |
|
251 if( ret != KErrNone ) |
|
252 { |
|
253 C_TRACE( ( _T( "usbpnstarter # E32Main() - CreateGenericCdcInterface failed.") ) ); |
|
254 return ret; |
|
255 } |
|
256 C_TRACE( ( _T( "usbpnstarter # E32Main() - Going to infinite loop") ) ); |
|
257 while( 1 ); // Stay on forever. Usbpnserver will destroy itself when there are no clients. |
|
258 |
|
259 } |
|
260 |
|
261 // End of File |