85 |
85 |
86 #ifdef USE_ACM_REGISTRATION_PORT |
86 #ifdef USE_ACM_REGISTRATION_PORT |
87 iComm.Close(); |
87 iComm.Close(); |
88 iCommServer.Close(); |
88 iCommServer.Close(); |
89 #else |
89 #else |
90 // Clean up any interface name strings |
90 iAcmServer.Close(); |
91 for ( TUint i = 0 ; i < KMaximumAcmFunctions ; i++ ) |
|
92 { |
|
93 iAcmControlIfcName[i].Close(); |
|
94 iAcmDataIfcName[i].Close(); |
|
95 } |
|
96 iAcmServer.Close(); |
|
97 #endif // USE_ACM_REGISTRATION_PORT |
91 #endif // USE_ACM_REGISTRATION_PORT |
98 } |
92 } |
99 |
93 |
100 /** |
94 /** |
101 * Constructor. |
95 * Constructor. |
102 * |
96 * |
103 * @param aOwner USB Device that owns and manages the class |
97 * @param aOwner USB Device that owns and manages the class |
104 */ |
98 */ |
105 CUsbACMClassController::CUsbACMClassController( |
99 CUsbACMClassController::CUsbACMClassController( |
106 MUsbClassControllerNotify& aOwner) |
100 MUsbClassControllerNotify& aOwner) |
107 : CUsbClassControllerPlugIn(aOwner, KAcmStartupPriority), |
101 : CUsbClassControllerPlugIn(aOwner, KAcmStartupPriority), |
108 iNumberOfAcmFunctions(KDefaultNumberOfAcmFunctions) |
102 iNumberOfAcmFunctions(KDefaultNumberOfAcmFunctions) |
109 { |
103 { |
110 // Initialise all elements to KDefaultAcmProtocolNum. |
104 } |
111 for ( TUint ii = 0 ; ii < KMaximumAcmFunctions ; ii++ ) |
|
112 { |
|
113 iAcmProtocolNum[ii] = KDefaultAcmProtocolNum; |
|
114 // iAcmControlIfcName[ii] and iAcmDataIfcName[ii] are already set to empty strings (RBuf); |
|
115 } |
|
116 } |
|
117 |
105 |
118 /** |
106 /** |
119 * 2nd Phase Construction. |
107 * 2nd Phase Construction. |
120 */ |
108 */ |
121 void CUsbACMClassController::ConstructL() |
109 void CUsbACMClassController::ConstructL() |
122 { |
110 { |
123 //open ini file to find out how many acm functions are needed and read in their configuration data |
111 iNumberOfAcmFunctions = KUsbAcmNumberOfAcmFunctions; |
124 ReadAcmConfigurationL(); |
112 |
|
113 iAcmProtocolNum[0] = KUsbAcmProtocolNumAcm1; |
|
114 iAcmProtocolNum[1] = KUsbAcmProtocolNumAcm2; |
|
115 iAcmProtocolNum[2] = KUsbAcmProtocolNumAcm3; |
|
116 iAcmProtocolNum[3] = KUsbAcmProtocolNumAcm4; |
|
117 iAcmProtocolNum[4] = KUsbAcmProtocolNumAcm5; |
125 |
118 |
126 // Prepare to use whichever mechanism is enabled to control bringing ACM |
119 // Prepare to use whichever mechanism is enabled to control bringing ACM |
127 // functions up and down. |
120 // functions up and down. |
128 #ifdef USE_ACM_REGISTRATION_PORT |
121 #ifdef USE_ACM_REGISTRATION_PORT |
129 |
122 |
135 // open it. |
128 // open it. |
136 LEAVEIFERRORL(iComm.Open(iCommServer, portName, ECommShared)); |
129 LEAVEIFERRORL(iComm.Open(iCommServer, portName, ECommShared)); |
137 |
130 |
138 #else |
131 #else |
139 |
132 |
140 LEAVEIFERRORL(iAcmServer.Connect()); |
133 LEAVEIFERRORL(iAcmServer.Connect()); |
141 |
134 |
142 #endif // USE_ACM_REGISTRATION_PORT |
135 #endif // USE_ACM_REGISTRATION_PORT |
143 } |
136 } |
144 |
137 |
145 /** |
|
146 * Searches numberofacmfunctions.ini file for protocol number and for control and data |
|
147 * interface names, leaving if any is not found. |
|
148 */ |
|
149 void CUsbACMClassController::ReadAcmIniDataL(CIniFile* aIniFile, TUint aCount, RBuf& aAcmControlIfcName, RBuf& aAcmDataIfcName) |
|
150 { |
|
151 LOG_FUNC |
|
152 |
|
153 TName sectionName; |
|
154 TInt protocolNum; |
|
155 |
|
156 #ifdef __FLOG_ACTIVE |
|
157 TName acmProtocolNum(KAcmProtocolNum); |
|
158 TBuf8<KMaxName> narrowAcmProtocolNum; |
|
159 narrowAcmProtocolNum.Copy(acmProtocolNum); |
|
160 #endif |
|
161 LOGTEXT3(_L8("\tLooking for ACM Section %d, keyword \"%S\""), aCount+1, &narrowAcmProtocolNum); |
|
162 |
|
163 sectionName.Format(KAcmSettingsSection,(aCount+1)); |
|
164 |
|
165 #ifdef __FLOG_ACTIVE |
|
166 // Set up useful narrow logging strings. |
|
167 TBuf8<KMaxName> narrowSectionName; |
|
168 narrowSectionName.Copy(sectionName); |
|
169 #endif |
|
170 LOGTEXT2(_L8("\t Section Name %S"), &narrowSectionName); |
|
171 |
|
172 if (aIniFile->FindVar(sectionName, KAcmProtocolNum(), protocolNum)) |
|
173 { |
|
174 LOGTEXT3(_L8("\tACM Section %d: Protocol No %d"),aCount+1, protocolNum); |
|
175 iAcmProtocolNum[aCount] = static_cast<TUint8>(protocolNum); |
|
176 } |
|
177 |
|
178 // Search ini file for interface names. If either of the interface names does not exist then the |
|
179 // descriptors remain at zero length. This is caught in DoStartL and the descriptors defaulted. |
|
180 // Using this method saves memory on storing copies of the default interface names. |
|
181 TPtrC ptrControlIfcName; |
|
182 if (aIniFile->FindVar(sectionName, KAcmControlIfcName(), ptrControlIfcName)) |
|
183 { |
|
184 TPtrC ptrDataIfcName; |
|
185 if (aIniFile->FindVar(sectionName, KAcmDataIfcName(), ptrDataIfcName)) |
|
186 { |
|
187 // Only copy the data if both interface names are valid |
|
188 aAcmControlIfcName.CreateL(ptrControlIfcName); |
|
189 aAcmControlIfcName.CleanupClosePushL(); |
|
190 aAcmDataIfcName.CreateL(ptrDataIfcName); |
|
191 CleanupStack::Pop(&aAcmControlIfcName); |
|
192 } |
|
193 } |
|
194 |
|
195 #ifdef __FLOG_ACTIVE |
|
196 // Set up useful narrow logging strings. |
|
197 TName dbgControlIfcName(aAcmControlIfcName); |
|
198 TBuf8<KMaxName> narrowControlIfcName; |
|
199 narrowControlIfcName.Copy(dbgControlIfcName); |
|
200 |
|
201 TName dbgDataIfcName(aAcmDataIfcName); |
|
202 TBuf8<KMaxName> narrowDataIfcName; |
|
203 narrowDataIfcName.Copy(dbgDataIfcName); |
|
204 #endif |
|
205 LOGTEXT2(_L8("\t Control Interface Name %S"), &narrowControlIfcName); |
|
206 LOGTEXT2(_L8("\t Data Interface Name %S"), &narrowDataIfcName); |
|
207 } |
|
208 |
|
209 /** |
|
210 Called when class Controller constructed |
|
211 It opens a numberofacmfunctions.ini file and gets the info from there |
|
212 Error behaviour: |
|
213 If the ini file is not found the number of ACM functions, their protocol |
|
214 settings and interface names will be the default values. |
|
215 If a memory error occurs then leaves with KErrNoMemory. |
|
216 If the ini file is created but the file contains invalid configuration then panic. |
|
217 */ |
|
218 void CUsbACMClassController::ReadAcmConfigurationL() |
|
219 { |
|
220 LOG_FUNC |
|
221 |
|
222 // The number of ACM functions should at this point be as set in the |
|
223 // constructor. |
|
224 __ASSERT_DEBUG(static_cast<TUint>(iNumberOfAcmFunctions) == KDefaultNumberOfAcmFunctions, |
|
225 _USB_PANIC(KAcmCcPanicCategory, EPanicBadNumberOfAcmFunctions)); |
|
226 |
|
227 LOGTEXT3(_L("\ttrying to open file \"%S\" in directory \"%S\""), |
|
228 &KAcmFunctionsIniFileName, &KUsbManPrivatePath); |
|
229 |
|
230 // First find the file |
|
231 CIniFile* iniFile = NULL; |
|
232 TRAPD (error, iniFile = CIniFile::NewL(KAcmFunctionsIniFileName, KUsbManPrivatePath)); |
|
233 |
|
234 if (error == KErrNotFound) |
|
235 { |
|
236 LOGTEXT(_L8("\tfile not found")); |
|
237 } |
|
238 else if (error != KErrNone) |
|
239 { |
|
240 LOGTEXT(_L8("\tini file was found, but couldn't be opened")); |
|
241 LEAVEL(error); |
|
242 } |
|
243 else |
|
244 { |
|
245 LOGTEXT(_L8("\tOpened ini file")); |
|
246 LOGTEXT3(_L("\tLooking for Section \"%S\", keyword \"%S\""), |
|
247 &KAcmConfigSection, &KNumberOfAcmFunctionsKeyWord); |
|
248 |
|
249 CleanupStack::PushL(iniFile); |
|
250 if ( !iniFile->FindVar(KAcmConfigSection(), KNumberOfAcmFunctionsKeyWord(), iNumberOfAcmFunctions) ) |
|
251 { |
|
252 // PANIC since this should only happen in development environment. |
|
253 // The file is incorrectly written. |
|
254 LOGTEXT(_L8("\tCan't find item")); |
|
255 _USB_PANIC(KAcmCcPanicCategory, EPanicBadNumberOfAcmFunctions); |
|
256 } |
|
257 |
|
258 LOGTEXT2(_L8("\tini file specifies %d ACM function(s)"), iNumberOfAcmFunctions); |
|
259 |
|
260 for ( TUint i = 0 ; i < iNumberOfAcmFunctions ; i++ ) |
|
261 { |
|
262 // Search ini file for the protocol number and interface names for |
|
263 // the function, using defaults if any are not found. |
|
264 // May leave with KErrNoMemory. |
|
265 ReadAcmIniDataL(iniFile, i, iAcmControlIfcName[i], iAcmDataIfcName[i]); |
|
266 } |
|
267 CleanupStack::PopAndDestroy(iniFile); |
|
268 } |
|
269 } |
|
270 |
|
271 /** |
138 /** |
272 * Called by UsbMan when it wants to start the USB ACM class. This always |
139 * Called by UsbMan when it wants to start the USB ACM class. This always |
273 * completes immediately. |
140 * completes immediately. |
274 * |
141 * |
275 * @param aStatus The caller's request status, filled in with an error code |
142 * @param aStatus The caller's request status, filled in with an error code |
291 void CUsbACMClassController::DoStartL() |
158 void CUsbACMClassController::DoStartL() |
292 { |
159 { |
293 LOG_FUNC |
160 LOG_FUNC |
294 |
161 |
295 iState = EUsbServiceStarting; |
162 iState = EUsbServiceStarting; |
|
163 LOGTEXT2(_L8(" iNumberOfAcmFunctions = %d"), iNumberOfAcmFunctions); |
296 |
164 |
297 #ifdef USE_ACM_REGISTRATION_PORT |
165 #ifdef USE_ACM_REGISTRATION_PORT |
298 |
166 |
299 // Create ACM functions. |
167 // Create ACM functions. |
300 TUint acmSetting; |
168 TUint acmSetting; |
301 for ( TUint i = 0 ; i < iNumberOfAcmFunctions ; i++ ) |
169 for (TUint i = 0; i < iNumberOfAcmFunctions; i++) |
302 { |
170 { |
303 // indicate the number of ACMs to create, and its protocol number (in the 3rd-lowest byte) |
171 LOGTEXT2(_L8(" iAcmProtocolNum[i] = %d"), iAcmProtocolNum[i]); |
304 acmSetting = 1 | (static_cast<TUint>(iAcmProtocolNum[i])<< 16); |
172 |
305 TInt err = iComm.SetSignalsToMark(acmSetting); |
173 // indicate the number of ACMs to create, and its protocol number (in the 3rd-lowest byte) |
306 if ( err != KErrNone ) |
174 acmSetting = 1 | (static_cast<TUint> (iAcmProtocolNum[i]) << 16); |
307 { |
175 TInt err = iComm.SetSignalsToMark(acmSetting); |
308 LOGTEXT2(_L8(" SetSignalsToMark error = %d"), err); |
176 if (err != KErrNone) |
309 if (i != 0) |
177 { |
310 { |
178 LOGTEXT2(_L8(" SetSignalsToMark error = %d"), err); |
311 // Must clear any ACMs that have completed. |
179 if (i != 0) |
312 // only other than KErrNone if C32 Server fails |
180 { |
313 (void)iComm.SetSignalsToSpace(i); |
181 // Must clear any ACMs that have completed. |
314 } |
182 // only other than KErrNone if C32 Server fails |
315 LEAVEL(err); |
183 (void) iComm.SetSignalsToSpace(i); |
316 } |
184 } |
317 } |
185 LEAVEL(err); |
|
186 } |
|
187 } |
318 |
188 |
319 #else // use ACM server |
189 #else // use ACM server |
320 |
190 // Create ACM functions |
321 // Create ACM functions |
191 for ( TInt i = 0; i < iNumberOfAcmFunctions; i++ ) |
322 for ( TInt i = 0 ; i < iNumberOfAcmFunctions ; i++ ) |
192 { |
323 { |
193 TInt err; |
324 TInt err; |
194 //Use default control interface name and data interface name |
325 // Check for zero length descriptor and default it if so |
195 //For improving performance, control interface name and data interface name configurable |
326 if (iAcmControlIfcName[i].Length()) |
196 //is not supported now. |
327 { |
197 err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], KControlIfcName, KDataIfcName); |
328 err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], iAcmControlIfcName[i], iAcmDataIfcName[i]); |
198 |
329 } |
199 if ( err != KErrNone ) |
330 else |
200 { |
331 { |
201 LOGTEXT2(_L8("\tFailed to create ACM function. Error: %d"), err); |
332 err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], KControlIfcName, KDataIfcName); |
202 if (i != 0) |
333 } |
203 { |
334 |
204 //Must clear any ACMs that have been completed |
335 if ( err != KErrNone ) |
205 iAcmServer.DestroyFunctions(i); |
336 { |
206 LOGTEXT2(_L8("\tDestroyed %d Interfaces"), i); |
337 LOGTEXT2(_L8("\tFailed to create ACM function. Error: %d"), err); |
207 } |
338 if (i != 0) |
208 LEAVEL(err); |
339 { |
209 } |
340 //Must clear any ACMs that have been completed |
210 } |
341 iAcmServer.DestroyFunctions(i); |
|
342 LOGTEXT2(_L8("\tDestroyed %d Interfaces"), i); |
|
343 } |
|
344 LEAVEL(err); |
|
345 } |
|
346 } |
|
347 |
211 |
348 #endif // USE_ACM_REGISTRATION_PORT |
212 #endif // USE_ACM_REGISTRATION_PORT |
349 |
213 |
350 LOGTEXT2(_L8("\tCreated %d ACM Interfaces"), iNumberOfAcmFunctions); |
214 LOGTEXT2(_L8("\tCreated %d ACM Interfaces"), iNumberOfAcmFunctions); |
351 } |
215 } |