Help on Telephony application

Login to reply to this topic.
Sat, 2005-12-24 12:31
Joined: 2005-08-24
Forum posts: 34
Hello,

Well I have been working on a telephony application which essentially deals with invoking the application when a phone call is recd. by a mobile device

Initially the application that I was studying gets activated (comes to foreground) when a call is recd. by the device & straightaway starts answering the call

What I want to do is when a call is recd. the application shld come to foregrnd which it does & ask the user whether he wants to accept or reject the incoming call which I am trying to acheive but somehow I can't.

Can anybody help me out by providing a small code snippet if not the entire code to do the above mentioned task ??


Thanks,

Yogesh Khanolkar

Sun, 2005-12-25 10:15
Joined: 2004-11-25
Forum posts: 12
Re: Help on Telephony application
Hi There,

I am trying to do the same thing. The point here is
to completely disable the default call handler of
the phone. I haven't found yet how to do it.
I will try to search / investigate.
Can anybody help?

Panayotis

panayotis

Tue, 2005-12-27 05:56
Joined: 2005-08-24
Forum posts: 34
Re: Help on Telephony application
Hello again...

Well just need to know if any particular function can be used to notify an incoming call & take action whether to accept/reject the call

Here I have been playing with NotifyIncomingCall() of RCall class & then passing the status as EStatusRinging to the application so that the user can Accept/Reject the call

But somehow cant get it

Can anybody guide me out of this



Thanks,

Yogesh Khanolkar
Tue, 2005-12-27 07:09
Joined: 2004-11-25
Forum posts: 12
Re: Help on Telephony application
Hi Yogesh,

NotifyIncomingCall() is the correct method to use
in order to be notified for the incoming call (at least
the one I use myself).  The whole logic should be
encoded inside your CActive object, RunL() and
StartL() methods. I suppose that you StartL()
method sends the NotifyIncomingCall() request and
the RunL() method waits for the completion of the
request. Use a simple state machine on your
CActive object to make sure that when the RunL()
method is called by the framework, objeck knows
what to do.

This is in general what it has to be done.
You are saying that "but somehow cant get it".

What exactly do you get and what you don't?
Can you be more specific? Do you want to post your
CActive object code in order for us to check that you
have it done correctly?

Panayotis

panayotis

Tue, 2005-12-27 13:41
Joined: 2005-08-24
Forum posts: 34
Re: Help on Telephony application
Hi,

Oh yes let me be more specific on what I am doing exactly

First let me tell u how it was earlier, this is for the CallReceiver class where the asynchronous process is happening

I will just concentrate on StartL() & RunL() methods

Code:

//StartL() starts here---

void CCallReceiver::StartL()
        {
        switch(iState)
                {
                case EWaiting:
                        // sets iCallName when it receives an incoming call
                        iLine.NotifyIncomingCall(iStatus, iCallName);
                        callreclog.Write(_L("StartL - EWaiting"));
                        break;

                case EAnswering:
                        User::LeaveIfError(iCall.OpenExistingCall(iLine, iCallName));
                        iCall.AnswerIncomingCall(iStatus);
                        callreclog.Write(_L("StartL - EAnswering"));
                        break;

                case EWatching:
                        callreclog.Write(_L("StartL - EWatching"));
                        iCall.NotifyStatusChange(iStatus, iCallStatus);
                        break;
                }
        SetActive();
        }

//RunL() starts here-----

void CCallReceiver::RunL()
        {
        if(iStatus.Int() != KErrNone)
                return;

        switch(iState)
                {
                case EWaiting:
                        {
                        //answer the call
                        iState = EAnswering;
                        callreclog.Write(_L("RunL() EWaiting"));
                        StartL();
                        break;
                        }

                case EAnswering:
                        {
                        iState = EWatching;
                        callreclog.Write(_L("RunL() EAnswering"));
                        StartL();
                        callreclog.Write(_L("HandleCallInChangeL called"));
                        iObserver.HandleCallInChangeL(RCall::EStatusConnected);
                        callreclog.Write(_L("HandleCallInChangeL completed"));
                        break;
                        }

                case EWatching: // To check whether the caller has hung up or not
                        {
                        User::LeaveIfError(iCall.GetStatus(iCallStatus));
                        callreclog.Write(_L("RunL() EWatching"));
                        if (iCallStatus == RCall::EStatusHangingUp)
                                {
                                iObserver.HandleCallInChangeL(iCallStatus);
                                iCall.Close();
                                iState = EWaiting;
                                }
                        StartL();
                        break;
                        }
                }
        }


As seen above the class waits for the incoming call & straightaway starts answering the call... Now as I said earlier I want to let the user know that a call has been recd. before the call can be answered

So I made the following changes in the above code

Code:

//StartL() starts here-----

void CCallReceiver::StartL()
        {
        switch(iState)
                {
                case EWaiting:
                        // sets iCallName when it receives an incoming call
                        iLine.NotifyIncomingCall(iStatus, iCallName);
                        callreclog.Write(_L("StartL - EWaiting"));
                        break;

                case EAnswering:
                        User::LeaveIfError(iCall.OpenExistingCall(iLine, iCallName));
                        iCall.AnswerIncomingCall(iStatus);
                        callreclog.Write(_L("StartL - EAnswering"));
                        break;

                case EWatching:
                        callreclog.Write(_L("StartL - EWatching"));
                        iCall.NotifyStatusChange(iStatus, iCallStatus);
                        break;
                }
        SetActive();
        }

//RunL() starts here-----

void CCallReceiver::RunL()
        {
        if(iStatus.Int() != KErrNone)
                return;

        switch(iState)
                {
                case EWaiting:
                        {
                        //notify the application, that a call is recd.     
                        iObserver.HandleCallInChangeL(RCall::EStatusRinging);
                        callreclog.Write(_L("RunL() EWaiting"));
                        break;
                        }

                case EAnswering:
                        {
                        iState = EWatching;
                        callreclog.Write(_L("RunL() EAnswering"));
                        StartL();
                        callreclog.Write(_L("HandleCallInChangeL called"));
                        iObserver.HandleCallInChangeL(RCall::EStatusConnected);
                        callreclog.Write(_L("HandleCallInChangeL completed"));
                        break;
                        }

                case EWatching: // To check whether the caller has hung up or not
                        {
                        User::LeaveIfError(iCall.GetStatus(iCallStatus));
                        callreclog.Write(_L("RunL() EWatching"));
                        if (iCallStatus == RCall::EStatusHangingUp)
                                {
                                iObserver.HandleCallInChangeL(iCallStatus);
                                iCall.Close();
                                iState = EWaiting;
                                }
                        StartL();
                        break;
                        }
                }
        }


& After intimating the application about the call, I am letting the user to Accept / Reject the call & then complete the asynchronous process of Answering the call OR Ending the Call

But now as soon as the call comes in & the application doesnot come into foreground & the default phone window takes the call as usual

Kindly let me know if any changes r required in the above code



Thanks,

Yogesh Khanolkar
Wed, 2005-12-28 20:48
Joined: 2004-11-25
Forum posts: 12
Re: Help on Telephony application
Hi there,

In your last code segment, the most recent, one,
I initially have a problem with your RunL() method,
which does not seem to change the state of the
active object on the EWaiting. In other words,
I would expect to have a change in state.
Hence, I will assume that the line:
Quote
iObserver.HandleCallInChangeL(RCall::EStatusRinging);
does the whole stuff about changing the state to
EAnswering or leaving it as it is EWaiting, depending
on user's reaction. Is that correct? Please confirm.

Now, if you want to bring your application on the
foreground, did you try to implement something
like the following (implementation of the
Quote
HandleForegroundEventL

Code:

void C<your AppUi class>AppUi::HandleForegroundEventL( TBool aForeground ) {

// Call Base class method

CAknAppUi::HandleForegroundEventL( aForeground );

    if ( !aForeground ) {

RWindowGroup * win;

win = & CCoeEnv::Static()->RootWin();

win->SetOrdinalPosition( 0, ECoeWinPriorityAlwaysAtFront );
    } // if not in foreground
} // end of the method

This piece of code will force your application to be
on the foreground. However, it may be a good idea to check inside the method about the call state (to be in ringing mode) and not just write the method
as I have it above. If you leave it as above, then
user will not be able to use any of the other applications in the phone unless he/she closes your
application.

Let me know if the above helps.

Panayotis

panayotis

Thu, 2005-12-29 12:38
Joined: 2005-08-24
Forum posts: 34
Re: Help on Telephony application
Hi Panayotis,

Yes I havent provided any state in the RunL() function as the function
Quote
iObserver.HandleCallInChangeL(RCall::EStatusRinging);
intimates the application about the incoming call & hence the function in the AppUi of the application brings the application to foreground

Simultaneously I am also changing the Command Button Array to Accept/Reject from the normal Options/Exit so that when the user selects the Accept key & only then I call a function from the CallReceiver Engine to accept the call

This function changes the state to EAnswering & then implements the following code as follows

User::LeaveIfError(iCall.OpenExistingCall(iLine, iCallName));
iCall.AnswerIncomingCall(iStatus);


This is how it should work but it doesnt

Also let me tell about the function that brings the application to foreground that I am implementing is as follows

Code:
TApaTaskList taskList(iCoeEnv->WsSession());
TApaTask currentTask = taskList.FindByPos(0);
TApaTask ourAppTask = taskList.FindApp(KUidTestPhone);
if(currentTask.ThreadId() != ourAppTask.ThreadId())
            ourAppTask.BringToForeground();

Now this code worked earlier when I was answering the call without intimating the user about the call i.e I was bringing the application to foreground as soon as a call was received & answered according to the code provided in my earlier posts

Quote
First let me tell u how it was earlier, this is for the CallReceiver class where the asynchronous process is happening

But now after the changes I made the same code for bringing the application to foreground doesnot work

Also I tried using the code provided by u for bringing the app. to foreground but it doesnot work either

The function that you provided
CAknAppUi::HandleForegroundEventL( aForeground );
is for events happening when the application is in the foreground & not for bringing the application to foreground

Please comment on this 1, & let me know about this

Thanks,

Yogesh
Thu, 2005-12-29 18:40
Joined: 2004-11-25
Forum posts: 12
Re: Help on Telephony application
Hi Yogesh,

you are saying that:

Quote
The function that you provided
CAknAppUi::HandleForegroundEventL( aForeground );
is for events happening when the application is in the foreground & not for bringing the application to foreground

I do not agree with you. This is the method that is
called by the Windoes Server framework to inform
notify an application that will be brought to
foreground or background (depending on the value
of "aForeground").

Hence, the expected behaviour of the code that I
gave you is the following: The default call handler
of your phone will NEVER come to foreground
(or any application) and always your application
will be on the foreground.

It works on my similar application. I do not
understand why it does not work on yours.

I am doing development using NOKIA 7610.

What is the phone you are using for your
development?

If you want to send me by e-mail (it is published)
all of your source code I could find out what is
going on and let you know. It's up to you.

BR
Panayotis

panayotis

Tue, 2006-01-10 07:56
Joined: 2005-08-24
Forum posts: 34
Re: Help on Telephony application
Hello,

I am working on a telephony application which deals with incoming calls. I have a Phone Engine which deals with the basic connectivity with the RTelServer. I also have a CallReceiver class which is specifically meant for dealing with incoming calls

Whenever an incoming call comes in, the application comes into foreground & asks the user whether he wants to Accept/Reject the incoming call & upon selection accordingly accepts/rejects the call

But when I press the Accept button the call doesnot get answered

Following is the code that I am trying from the Call Receiver class

Code:
void CCallReceiver::RunL()
        {
        callreclog.Write(_L("### CCallReceiver::RunL() = 1 ###"));

        if(iStatus.Int() != KErrNone)
        {
              callreclog.Write(_L("### CCallReceiver::RunL() = 2 ###"));
              return;
        }

        switch(iState)
                {
                case EWaiting:  // To intimate the application abyt the incoming call arrived
                        callreclog.Write(_L("RunL() EWaiting"));
                        iState = ERinging;
                        StartL();
                        callreclog.Write(_L("HandleCallInChangeL called"));
                        iObserver.HandleCallInChangeL(RCall::EStatusRinging);
                        callreclog.Write(_L("HandleCallInChangeL completed"));
                        break;

                case ERinging:  // To decide the status of the incoming call
                        callreclog.Write(_L("RunL() ERinging"));

                        if ( iCheckStatus == EAccept )  // Call accepted
                        {
                            callreclog.Write(_L("EAccept Apprvd."));
                            iState = EAnswering;
                            StartL();
                            break;
                        }

                        if ( iCheckStatus == EReject )  // Call rejected
                        {
                            callreclog.Write(_L("EReject Apprvd."));
                            iObserver.HandleCallInChangeL(RCall::EStatusHangingUp);
                            iState = EWaiting;
                            StartL();
                            break;
                        }

                        User::LeaveIfError(iLine.GetStatus(iLineStatus));

                        if (iLineStatus == RCall::EStatusHangingUp) // Call hungup by the caller
                        {
                            //Caller hung up before the call was accepted / rejected
                            callreclog.Write(_L("Caller HungUp"));
                            iObserver.HandleCallInChangeL(iLineStatus);
                            iState = EWaiting;
                            StartL();
                            break;
                        }

                case EAnswering: // To answer the accepted incoming call
                        callreclog.Write(_L("RunL() EAnswering"));
                        iState = EWatching;
                        StartL();
                        callreclog.Write(_L("HandleCallInChangeL called"));
                        iObserver.HandleCallInChangeL(RCall::EStatusConnected);
                        callreclog.Write(_L("HandleCallInChangeL completed"));
                        break;

                case EWatching: // To check whether the caller has hung up or not
                        User::LeaveIfError(iCall.GetStatus(iCallStatus));
                        callreclog.Write(_L("RunL() EWatching"));
                        if (iCallStatus == RCall::EStatusHangingUp)
                                {
                                iObserver.HandleCallInChangeL(iCallStatus);
                                iCall.Close();
                                iState = EWaiting;
                                }
                        StartL();
                        break;
                } // End of switch
        }

void CCallReceiver::StartL()
        {
        switch(iState)
                {
                case EWaiting: // Sets iCallName when it receives an incoming call
                        iLine.NotifyIncomingCall(iStatus, iCallName);
                        callreclog.Write(_L("StartL - EWaiting"));
                        break;

                case ERinging:  // Notifies the change in status of iLine
                        callreclog.Write(_L("StartL - ERinging"));
                        iLine.NotifyStatusChange(iStatus, iLineStatus);
                        break;

                case EAnswering:  // Opens existing call & answers it
                        callreclog.Write(_L("StartL - EAnswering"));
                        User::LeaveIfError(iCall.OpenExistingCall(iLine, iCallName));
                        callreclog.Write(_L("Opens Existing Call"));
                        iCall.AnswerIncomingCall(iStatus);
                        callreclog.Write(_L("Answers Incoming Call"));
                        break;

                case EWatching: // Notifies the change in status of iCall
                        callreclog.Write(_L("StartL - EWatching"));
                        iCall.NotifyStatusChange(iStatus, iCallStatus);
                        break;
                }

        SetActive();

        callreclog.Write(_L("SetActive called"));
        }


In the above code when it comes to Answering the Call (StartL() method for EAnswering) the SetActive gets called but when it enters the RunL() method the control returns from the line

Quote
if(iStatus.Int() != KErrNone)
        {
              callreclog.Write(_L("### CCallReceiver::RunL() = 2 ###"));
              return;
        }

Please help me out in this,

Thanks,
 
Yogesh
  • Login to reply to this topic.