35 */ |
35 */ |
36 : CActive(CActive::EPriorityStandard), |
36 : CActive(CActive::EPriorityStandard), |
37 iBreakState(EInactive), |
37 iBreakState(EInactive), |
38 iParentAcm(aParentAcm) |
38 iParentAcm(aParentAcm) |
39 { |
39 { |
|
40 OstTraceFunctionEntry0( CBREAKCONTROLLER_CBREAKCONTROLLER_CONS_ENTRY ); |
40 CActiveScheduler::Add(this); |
41 CActiveScheduler::Add(this); |
41 |
42 |
42 // now populate the state machine that manages the transfers between |
43 // now populate the state machine that manages the transfers between |
43 // the declared state values of TBreakState. |
44 // the declared state values of TBreakState. |
44 TInt oldBS; |
45 TInt oldBS; |
64 StateDispatcher[ETiming ][ETiming ] = &ScSetTimer; |
65 StateDispatcher[ETiming ][ETiming ] = &ScSetTimer; |
65 StateDispatcher[ETiming ][ELocked ] = &ScLocked; |
66 StateDispatcher[ETiming ][ELocked ] = &ScLocked; |
66 |
67 |
67 StateDispatcher[ELocked ][EInactive ] = &ScInactive; |
68 StateDispatcher[ELocked ][EInactive ] = &ScInactive; |
68 StateDispatcher[ELocked ][ETiming ] = &ScSetTimer; |
69 StateDispatcher[ELocked ][ETiming ] = &ScSetTimer; |
|
70 OstTraceFunctionExit0( CBREAKCONTROLLER_CBREAKCONTROLLER_CONS_EXIT ); |
69 } |
71 } |
70 |
72 |
71 CBreakController* CBreakController::NewL(CCdcAcmClass& aParentAcm) |
73 CBreakController* CBreakController::NewL(CCdcAcmClass& aParentAcm) |
72 /** |
74 /** |
73 * Factory function. |
75 * Factory function. |
74 * |
76 * |
75 * @param aParentAcm Parent. |
77 * @param aParentAcm Parent. |
76 * @return Ownership of a new CBreakController object. |
78 * @return Ownership of a new CBreakController object. |
77 */ |
79 */ |
78 { |
80 { |
79 LOG_STATIC_FUNC_ENTRY |
81 OstTraceFunctionEntry0( CBREAKCONTROLLER_NEWL_ENTRY ); |
80 |
|
81 CBreakController* self = new(ELeave) CBreakController(aParentAcm); |
82 CBreakController* self = new(ELeave) CBreakController(aParentAcm); |
82 CleanupStack::PushL(self); |
83 CleanupStack::PushL(self); |
83 self->ConstructL(); |
84 self->ConstructL(); |
84 CLEANUPSTACK_POP(self); |
85 CLEANUPSTACK_POP(self); |
|
86 OstTraceFunctionExit0( CBREAKCONTROLLER_NEWL_EXIT ); |
85 return self; |
87 return self; |
86 } |
88 } |
87 |
89 |
88 void CBreakController::ConstructL() |
90 void CBreakController::ConstructL() |
89 /** |
91 /** |
90 * 2nd-phase constructor. |
92 * 2nd-phase constructor. |
91 */ |
93 */ |
92 { |
94 { |
93 LEAVEIFERRORL(iTimer.CreateLocal()); |
95 TInt err; |
|
96 err = iTimer.CreateLocal(); |
|
97 if (err < 0) |
|
98 { |
|
99 OstTrace1( TRACE_NORMAL, CBREAKCONTROLLER_CONSTRUCTL, "CBreakController::ConstructL;err=%d", err ); |
|
100 User::Leave(err); |
|
101 } |
94 } |
102 } |
95 |
103 |
96 CBreakController::~CBreakController() |
104 CBreakController::~CBreakController() |
97 /** |
105 /** |
98 * Destructor. |
106 * Destructor. |
99 */ |
107 */ |
100 { |
108 { |
101 LOG_FUNC |
109 OstTraceFunctionEntry0( CBREAKCONTROLLER_CBREAKCONTROLLER_DES_ENTRY ); |
102 |
|
103 Cancel(); |
110 Cancel(); |
104 iTimer.Close(); |
111 iTimer.Close(); |
|
112 OstTraceFunctionExit0( CBREAKCONTROLLER_CBREAKCONTROLLER_DES_EXIT ); |
105 } |
113 } |
106 |
114 |
107 void CBreakController::RunL() |
115 void CBreakController::RunL() |
108 /** |
116 /** |
109 * Called by the active scheduler; handles timer completion. |
117 * Called by the active scheduler; handles timer completion. |
110 */ |
118 */ |
111 { |
119 { |
112 LOG_LINE |
120 OstTraceFunctionEntry0( CBREAKCONTROLLER_RUNL_ENTRY ); |
113 LOG_FUNC |
121 |
114 |
|
115 // check the status to see if the timer has matured, if so go straight |
122 // check the status to see if the timer has matured, if so go straight |
116 // to INACTIVE state (and publish new state) |
123 // to INACTIVE state (and publish new state) |
117 if ( iStatus == KErrNone ) |
124 if ( iStatus == KErrNone ) |
118 { |
125 { |
119 // Use iRequester to turn the break off. This should not fail. |
126 // Use iRequester to turn the break off. This should not fail. |
120 TInt err = BreakRequest(iRequester, EInactive); |
127 TInt err = BreakRequest(iRequester, EInactive); |
121 static_cast<void>(err); |
128 static_cast<void>(err); |
122 __ASSERT_DEBUG(!err, |
129 if (err) |
123 _USB_PANIC(KAcmPanicCat, EPanicInternalError)); |
130 { |
124 } |
131 OstTrace1( TRACE_FATAL, CBREAKCONTROLLER_RUNL, "CBreakController::RunL;err=%d", err ); |
|
132 __ASSERT_DEBUG( EFalse, User::Panic(KAcmPanicCat, EPanicInternalError) ); |
|
133 } |
|
134 } |
|
135 OstTraceFunctionExit0( CBREAKCONTROLLER_RUNL_EXIT ); |
125 } |
136 } |
126 |
137 |
127 void CBreakController::DoCancel() |
138 void CBreakController::DoCancel() |
128 /** |
139 /** |
129 * Called by the framework; handles cancelling the outstanding timer request. |
140 * Called by the framework; handles cancelling the outstanding timer request. |
130 */ |
141 */ |
131 { |
142 { |
132 LOG_FUNC |
143 OstTraceFunctionEntry0( CBREAKCONTROLLER_DOCANCEL_ENTRY ); |
133 |
|
134 iTimer.Cancel(); |
144 iTimer.Cancel(); |
|
145 OstTraceFunctionExit0( CBREAKCONTROLLER_DOCANCEL_EXIT ); |
135 } |
146 } |
136 |
147 |
137 TInt CBreakController::BreakRequest(TRequester aRequester, |
148 TInt CBreakController::BreakRequest(TRequester aRequester, |
138 TState aState, |
149 TState aState, |
139 TTimeIntervalMicroSeconds32 aDelay) |
150 TTimeIntervalMicroSeconds32 aDelay) |
145 * make the break inactive. |
156 * make the break inactive. |
146 * @param aDelay The time delay, only used for a timed break. |
157 * @param aDelay The time delay, only used for a timed break. |
147 * @return Error, for instance if a different entity already owns the break. |
158 * @return Error, for instance if a different entity already owns the break. |
148 */ |
159 */ |
149 { |
160 { |
150 LOG_FUNC |
161 OstTraceFunctionEntry0( CBREAKCONTROLLER_BREAKREQUEST_ENTRY ); |
151 LOGTEXT4(_L8("\taRequester = %d, aState = %d, aDelay = %d"), |
162 OstTraceExt3( TRACE_NORMAL, CBREAKCONTROLLER_BREAKREQUEST, |
152 aRequester, aState, aDelay.Int()); |
163 "CBreakController::BreakRequest;aRequester=%d;aState=%d;aDelay=%d", (TInt)aRequester, (TInt)aState, aDelay.Int() ); |
153 |
164 |
154 // Check the validity of the request. |
165 // Check the validity of the request. |
155 if ( aRequester != iRequester && iRequester != ENone ) |
166 if ( aRequester != iRequester && iRequester != ENone ) |
156 { |
167 { |
157 LOGTEXT3(_L8("\t*** %d is in charge- cannot service request " |
168 OstTraceExt2( TRACE_FLOW, CBREAKCONTROLLER_BREAKREQUEST_DUP1, |
158 "from %d- returning KErrInUse"), iRequester, aRequester); |
169 "CBreakController::BreakRequest;%d is in charge- cannot service request from %d- returning KErrInUse", |
|
170 (TInt)iRequester, (TInt)aRequester ); |
|
171 |
|
172 OstTraceFunctionExit0( CBREAKCONTROLLER_BREAKREQUEST_EXIT ); |
159 return KErrInUse; |
173 return KErrInUse; |
160 } |
174 } |
161 |
175 |
162 iRequester = aRequester; |
176 iRequester = aRequester; |
163 |
|
164 StateMachine(aState, aDelay); |
177 StateMachine(aState, aDelay); |
165 |
|
166 // Reset the owner member if relevant. |
178 // Reset the owner member if relevant. |
167 if ( aState == EInactive ) |
179 if ( aState == EInactive ) |
168 { |
180 { |
169 iRequester = ENone; |
181 iRequester = ENone; |
170 } |
182 } |
171 |
183 |
|
184 OstTraceFunctionExit0( CBREAKCONTROLLER_BREAKREQUEST_EXIT_DUP1 ); |
172 return KErrNone; |
185 return KErrNone; |
173 } |
186 } |
174 |
187 |
175 void CBreakController::StateMachine(TState aBreakState, |
188 void CBreakController::StateMachine(TState aBreakState, |
176 TTimeIntervalMicroSeconds32 aDelay) |
189 TTimeIntervalMicroSeconds32 aDelay) |
179 * |
192 * |
180 * @param aBreakState The state to go to now. |
193 * @param aBreakState The state to go to now. |
181 * @param aDelay Only used if going to a breaking state, the delay. |
194 * @param aDelay Only used if going to a breaking state, the delay. |
182 */ |
195 */ |
183 { |
196 { |
184 LOG_FUNC |
197 OstTraceFunctionEntry0( CBREAKCONTROLLER_STATEMACHINE_ENTRY ); |
185 |
|
186 TBool resultOK = EFalse; |
198 TBool resultOK = EFalse; |
187 |
199 |
188 // Invoke the desired function. |
200 // Invoke the desired function. |
189 PBFNT pfsDispatch = StateDispatcher[iBreakState][aBreakState]; |
201 PBFNT pfsDispatch = StateDispatcher[iBreakState][aBreakState]; |
190 __ASSERT_DEBUG(pfsDispatch, |
202 if (!pfsDispatch) |
191 _USB_PANIC(KAcmPanicCat, EPanicInternalError)); |
203 { |
|
204 OstTraceExt1( TRACE_FATAL, CBREAKCONTROLLER_STATEMACHINE, "CBreakController::StateMachine;pfsDispatch=%p", (TAny*)pfsDispatch ); |
|
205 __ASSERT_DEBUG( EFalse, User::Panic(KAcmPanicCat, EPanicInternalError) ); |
|
206 } |
192 resultOK = ( *pfsDispatch )(this, aDelay); |
207 resultOK = ( *pfsDispatch )(this, aDelay); |
193 |
208 |
194 if ( resultOK ) |
209 if ( resultOK ) |
195 { |
210 { |
196 LOGTEXT(_L8("\tbreak state dispatcher returned *SUCCESS*")); |
211 OstTrace0( TRACE_NORMAL, CBREAKCONTROLLER_STATEMACHINE_DUP1, |
197 |
212 "CBreakController::StateMachine;\tbreak state dispatcher returned *SUCCESS*" ); |
|
213 |
198 // check to see if the state change will need to result |
214 // check to see if the state change will need to result |
199 // in a modification to the public state of BREAK which is |
215 // in a modification to the public state of BREAK which is |
200 // either NO-BREAK == EBreakInactive |
216 // either NO-BREAK == EBreakInactive |
201 // or BREAK-ON == (anything else) |
217 // or BREAK-ON == (anything else) |
202 if( ( iBreakState != aBreakState ) |
218 if( ( iBreakState != aBreakState ) |
212 // accept the state change ready for next time |
228 // accept the state change ready for next time |
213 iBreakState = aBreakState; |
229 iBreakState = aBreakState; |
214 } |
230 } |
215 else |
231 else |
216 { |
232 { |
217 LOGTEXT(_L8("\tbreak state dispatcher returned *FAILURE*")); |
233 OstTrace0( TRACE_NORMAL, CBREAKCONTROLLER_STATEMACHINE_DUP2, |
218 } |
234 "CBreakController::StateMachine;\tbreak state dispatcher returned *FAILURE*" ); |
|
235 } |
|
236 OstTraceFunctionExit0( CBREAKCONTROLLER_STATEMACHINE_EXIT ); |
219 } |
237 } |
220 |
238 |
221 void CBreakController::Publish(TState aNewState) |
239 void CBreakController::Publish(TState aNewState) |
222 /** |
240 /** |
223 * Pointer-safe method to inform the (USB) Host and the Client of BREAK |
241 * Pointer-safe method to inform the (USB) Host and the Client of BREAK |
224 * changes. |
242 * changes. |
225 * |
243 * |
226 * @param aNewState The next state we're about to go to. |
244 * @param aNewState The next state we're about to go to. |
227 */ |
245 */ |
228 { |
246 { |
229 LOG_FUNC |
247 OstTraceFunctionEntry0( CBREAKCONTROLLER_PUBLISH_ENTRY ); |
230 LOGTEXT2(_L8("\taNewState = %d"), aNewState); |
248 |
231 |
249 if (aNewState == iBreakState) |
232 __ASSERT_DEBUG(aNewState != iBreakState, |
250 { |
233 _USB_PANIC(KAcmPanicCat, EPanicInternalError)); |
251 OstTrace1( TRACE_FATAL, CBREAKCONTROLLER_PUBLISH, "CBreakController::Publish;aNewState=%d", (TInt)aNewState ); |
|
252 __ASSERT_DEBUG( EFalse, User::Panic(KAcmPanicCat, EPanicInternalError) ); |
|
253 } |
234 |
254 |
235 // send the new BREAK state off to the USB Host |
255 // send the new BREAK state off to the USB Host |
236 // this function is normally used so that ACMCSY can send client |
256 // this function is normally used so that ACMCSY can send client |
237 // changes to RING, DSR and DCD to the USB Host, however we use |
257 // changes to RING, DSR and DCD to the USB Host, however we use |
238 // it here to force it to refresh all states together with the |
258 // it here to force it to refresh all states together with the |
245 |
265 |
246 // inform the ACM Class client that the BREAK signal has just changed, |
266 // inform the ACM Class client that the BREAK signal has just changed, |
247 // this should cause it to be toggled there. |
267 // this should cause it to be toggled there. |
248 if( iParentAcm.BreakCallback() ) |
268 if( iParentAcm.BreakCallback() ) |
249 { |
269 { |
250 LOGTEXT(_L8("\tabout to call back break state change")); |
270 OstTrace0( TRACE_NORMAL, CBREAKCONTROLLER_PUBLISH_DUP1, "CBreakController::Publish;\tabout to call back break state change" ); |
251 iParentAcm.BreakCallback()->BreakStateChange(); |
271 iParentAcm.BreakCallback()->BreakStateChange(); |
252 } |
272 } |
253 |
273 |
254 // If we're going to the inactive state, and if the device is interested, |
274 // If we're going to the inactive state, and if the device is interested, |
255 // we tell the MBreakObserver (ACM port) that the break has completed. |
275 // we tell the MBreakObserver (ACM port) that the break has completed. |
256 if ( aNewState == EInactive ) |
276 if ( aNewState == EInactive ) |
257 { |
277 { |
258 LOGTEXT(_L8("\tnew state is break-inactive")); |
278 OstTrace0( TRACE_NORMAL, CBREAKCONTROLLER_PUBLISH_DUP2, "CBreakController::Publish;\tnew state is break-inactive" ); |
259 if ( iRequester == EDevice ) |
279 if ( iRequester == EDevice ) |
260 { |
280 { |
261 LOGTEXT(_L8("\tdevice is interested")); |
281 OstTrace0( TRACE_NORMAL, CBREAKCONTROLLER_PUBLISH_DUP3, "CBreakController::Publish;\tdevice is interested" ); |
262 if( iParentAcm.BreakCallback() ) |
282 if( iParentAcm.BreakCallback() ) |
263 { |
283 { |
264 LOGTEXT(_L8("\tabout to call back break completion")); |
284 OstTrace0( TRACE_NORMAL, CBREAKCONTROLLER_PUBLISH_DUP4, "CBreakController::Publish;\tabout to call back break completion" ); |
265 iParentAcm.BreakCallback()->BreakRequestCompleted(); |
285 iParentAcm.BreakCallback()->BreakRequestCompleted(); |
266 } |
286 } |
267 } |
287 } |
268 |
288 |
269 // We just got to break-inactive state. Blank the requester record. |
289 // We just got to break-inactive state. Blank the requester record. |
270 iRequester = ENone; |
290 iRequester = ENone; |
271 } |
291 } |
|
292 OstTraceFunctionExit0( CBREAKCONTROLLER_PUBLISH_EXIT ); |
272 } |
293 } |
273 |
294 |
274 /** |
295 /** |
275 * +----------------------------------------------+ |
296 * +----------------------------------------------+ |
276 * | Set of state-machine functions to be used in | |
297 * | Set of state-machine functions to be used in | |
279 */ |
300 */ |
280 |
301 |
281 TBool CBreakController::ScInvalid(CBreakController *aThis, |
302 TBool CBreakController::ScInvalid(CBreakController *aThis, |
282 TTimeIntervalMicroSeconds32 aDelay) |
303 TTimeIntervalMicroSeconds32 aDelay) |
283 { |
304 { |
284 LOG_STATIC_FUNC_ENTRY |
305 OstTraceFunctionEntry0( CBREAKCONTROLLER_SCINVALID_ENTRY ); |
285 |
|
286 static_cast<void>(aThis); // remove warning |
306 static_cast<void>(aThis); // remove warning |
287 static_cast<void>(aDelay); // remove warning |
307 static_cast<void>(aDelay); // remove warning |
288 |
308 OstTraceFunctionExit0( CBREAKCONTROLLER_SCINVALID_EXIT ); |
289 return( EFalse ); |
309 return( EFalse ); |
290 } |
310 } |
291 |
311 |
292 TBool CBreakController::ScInactive(CBreakController *aThis, |
312 TBool CBreakController::ScInactive(CBreakController *aThis, |
293 TTimeIntervalMicroSeconds32 aDelay) |
313 TTimeIntervalMicroSeconds32 aDelay) |
294 { |
314 { |
295 LOG_STATIC_FUNC_ENTRY |
315 OstTraceFunctionEntry0( CBREAKCONTROLLER_SCINACTIVE_ENTRY ); |
296 |
316 |
297 static_cast<void>(aDelay); // remove warning |
317 static_cast<void>(aDelay); // remove warning |
298 |
318 |
299 // this may have been called while a BREAK is already current, cancel the |
319 // this may have been called while a BREAK is already current, cancel the |
300 // timer. |
320 // timer. |
301 aThis->Cancel(); |
321 aThis->Cancel(); |
302 |
322 |
303 aThis->iParentAcm.SetBreakActive(EFalse); |
323 aThis->iParentAcm.SetBreakActive(EFalse); |
304 |
324 |
|
325 OstTraceFunctionExit0( CBREAKCONTROLLER_SCINACTIVE_EXIT ); |
305 return( ETrue ); |
326 return( ETrue ); |
306 } |
327 } |
307 |
328 |
308 TBool CBreakController::ScSetTimer(CBreakController *aThis, |
329 TBool CBreakController::ScSetTimer(CBreakController *aThis, |
309 TTimeIntervalMicroSeconds32 aDelay) |
330 TTimeIntervalMicroSeconds32 aDelay) |
310 { |
331 { |
311 LOG_STATIC_FUNC_ENTRY |
332 OstTraceFunctionEntry0( CBREAKCONTROLLER_SCSETTIMER_ENTRY ); |
312 |
333 |
313 // don't try to set any delay if the caller wants something impossible |
334 // don't try to set any delay if the caller wants something impossible |
314 if ( aDelay.Int() <= 0 ) |
335 if ( aDelay.Int() <= 0 ) |
315 { |
336 { |
|
337 OstTraceFunctionExit0( CBREAKCONTROLLER_SCSETTIMER_EXIT ); |
316 return( EFalse ); |
338 return( EFalse ); |
317 } |
339 } |
318 |
340 |
319 aThis->Cancel(); // in case we're already active. |
341 aThis->Cancel(); // in case we're already active. |
320 |
342 |
321 aThis->iTimer.After(aThis->iStatus, aDelay); |
343 aThis->iTimer.After(aThis->iStatus, aDelay); |
322 aThis->SetActive(); |
344 aThis->SetActive(); |
323 |
345 |
324 aThis->iParentAcm.SetBreakActive(ETrue); |
346 aThis->iParentAcm.SetBreakActive(ETrue); |
325 |
347 |
|
348 OstTraceFunctionExit0( CBREAKCONTROLLER_SCSETTIMER_EXIT_DUP1 ); |
326 return( ETrue ); |
349 return( ETrue ); |
327 } |
350 } |
328 |
351 |
329 TBool CBreakController::ScLocked(CBreakController *aThis, |
352 TBool CBreakController::ScLocked(CBreakController *aThis, |
330 TTimeIntervalMicroSeconds32 aDelay) |
353 TTimeIntervalMicroSeconds32 aDelay) |
331 { |
354 { |
332 LOG_STATIC_FUNC_ENTRY |
355 OstTraceFunctionEntry0( CBREAKCONTROLLER_SCLOCKED_ENTRY ); |
333 |
|
334 static_cast<void>(aDelay); // remove warning |
356 static_cast<void>(aDelay); // remove warning |
335 |
357 |
336 // this may have been called while a BREAK is already current, so cancel |
358 // this may have been called while a BREAK is already current, so cancel |
337 // the timer. |
359 // the timer. |
338 aThis->Cancel(); |
360 aThis->Cancel(); |
339 |
361 |
340 aThis->iParentAcm.SetBreakActive(ETrue); |
362 aThis->iParentAcm.SetBreakActive(ETrue); |
341 |
363 |
|
364 OstTraceFunctionExit0( CBREAKCONTROLLER_SCLOCKED_EXIT ); |
342 return( ETrue ); |
365 return( ETrue ); |
343 } |
366 } |
344 |
367 |
345 // |
368 // |
346 // End of file |
369 // End of file |