CTimer problem
| Sun, 2008-04-27 15:22 | |
|
Hi Thank you void CActiveClass::TimerExpired()
{
RunL();
}
void CActiveClass::RunL()
{
// --- when call is connected ---
//if tone is "p" (pause)
{
dtmfIndex++;
TTimeIntervalMicroSeconds32 interval = 2000000;// 2 seconds
//###### 'PAUSE' DELAY - DOESN'T WORK - DTMF'S JUST CONTINUE #####
iTimeOutTimer->After(interval);
}
else // tone is numeric
{
iPhone.StartDTMFTone((DTMF_Buf->Des())[dtmfIndex]);// send DTMF
dtmfIndex++;
iPhone.StopDTMFTone();
TTimeIntervalMicroSeconds32 interval = 100000;
//### SHORT DELAY BETWEEN DTMF'S - WORKS WELL ###
iTimeOutTimer->After(interval);
}
iLine.NotifyStatusChange(iStatus, iCallStatus);
SetActive();
}
|
|






Forum posts: 588
What worries me is that you call RunL yourself -- something you should never do. Only the scheduler calls the RunL, when the async operation has been done.
Forum posts: 135
Thanks Andreas I will keep that in mind.
If I'll put this code (below) inside the TimerExpired() method, do you think it would be ok?
//if tone is "p" (pause) { dtmfIndex++; TTimeIntervalMicroSeconds32 interval = 2000000;// 2 seconds iTimeOutTimer->After(interval); } else // tone is numeric { iPhone.StartDTMFTone((DTMF_Buf->Des())[dtmfIndex]);// send DTMF dtmfIndex++; iPhone.StopDTMFTone(); TTimeIntervalMicroSeconds32 interval = 100000; iTimeOutTimer->After(interval); }Forum posts: 1142
are you really sure your timeout timer works at all?
Are you sure the delay isn't inside any of those dtmf functions or the line status?
to me that code looks a bit funky... what is the thought there?
If you have a active object that wants to send dtmf tones on some interval with the help of some timer, I would expect the runl to send new requests to the timer, but here you do some kind of request on an external timer, and then issue a request to the line status...
so next call to runl will not be when the timer times out, but when the line status request completes...
what is that iTimeouttimer and how is it supposed to work?
Forum posts: 135
Thank you for your reply alh
The iTimeouttimer inherits CTimer.
I tried to use RTimer also, this way (iTimer is a RTimer):
//### INSIDE CActive::RunL() - WHEN CALL STATUS IS CONNECTED ### while(dtmfIndex<DTMF_Buf->Length()) { if tone is 'p' { dtmfIndex++; iTimer.After(iStatus,2000000);//2 sec delay User::WaitForRequest(iStatus); } else { iPhone.StartDTMFTone((DTMF_Buf->Des())[dtmfIndex]); dtmfIndex++; iPhone.StopDTMFTone(); iTimer.After(iStatus,100000);//very short delay between DTMF's User::WaitForRequest(iStatus); } }I also tried User::After instead of iTimer.After.
The result was that the delay was much shorter than 2 seconds and further more - the rest of the DTMF's after the delay were not equal in their length and the short delay between them.
If you can suggest me a better way to do this, I'll be happy to hear about it !
Thank you very much
Forum posts: 1142
I would try splitting code up some, and not try to handle everything in the same CActive.
Trying to handle more then one kind of request in the same active object often gives weird and wonderful problems.
I would expect this second code block to work though (and also User::After), or at least not produce as weird results as you describe...
Sorry, don't think I can help much more then that...
Forum posts: 588
You shouldn't call User::WaitForRequest in RunL -- the AO framework (specifically, the CActiveScheduler) will do the waiting and call your RunL when the async request has been finished. Read a tutorial on using active objects, e.g. this: http://developer.symbian.com/main/downloads/papers/CActiveAndFriends/CActiveAndFriends.pdf
Also follow alh's suggestion to Keep It Simple Sir.
Forum posts: 135
Thank you both very much
Can you please explain what you mean by "splitting the code"?
Thanks
Forum posts: 588
Splitting the code means design -- design your classes to handle (optimally) only one thing per class. This is a good object oriented design heuristic. In practice, you can sometimes overlook this heuristic. So in your case let one active object handle one asynchronous service and implement another active object to handle some other asynchronous service.
Forum posts: 135
Hi Andreas
Thank you for the info.
Please advise,
what would be a good to communicate between 2 active objects? how can one object "tell" another objects to start a specific async request?
Thanks
Forum posts: 1142
The same way any other class would communicate to it, by storing a pointer or reference to the object and call a member function on it.
Forum posts: 588
// CA.h
class CB;
class CA : public CActive {
...
public:
void DoBeDoBeDooL();
...
private:
CB * iB;
};
// CB.h
class CB : public CActive {
...
public:
void DamDiDamDiDamL();
...
private:
RTimer iTimer;
};
//CA.cpp
...
void CA::DoBeDoBeDooL()
{
iB->DamDiDamDiDamL();
}
// CB.cpp
void CB::DamDiDamDIDamL()
{
iTimer.After(iStatus, 1000000);
SetActive();
}
Forum posts: 135
Great , That is what I thought,
Thank you very much for your help!