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