Read-only archive of the All About Symbian forum (2001–2013) · About this archive

Recieve incoming calls

4 replies · 3,381 views · Started 16 December 2004

Hello all. Can somebody help me? I tried to recive incoming call with code below, but it didn't work.

//----------- main.cpp ----------------------------------------------------------------------
#include <e32base.h>
#include <f32file.h>

#include "TelephonyWrapper.h"

const TUid KUidcontext_log = { 0x05CCC0AF };

// This is the mainloop game loop or whatever
void mainloop(void)
{
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler; // get active scheduler
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler); // install active scheduler

CTelephonyWrapper* tel_wrapper = new (ELeave) CTelephonyWrapper;
CleanupStack::PushL(tel_wrapper);
tel_wrapper->WaitCall();
CActiveScheduler::Start();

RTimer timer; // The asynchronous timer and ...
timer.CreateLocal(); // Always created for this thread.
CleanupClosePushL(timer);

TTime time;
time.HomeTime();

TTimeIntervalHours wait_interval(1);

time += wait_interval;

TRequestStatus timer_status;
timer.At(timer_status, time);

TBool done = EFalse;

while(!done)
{
User::WaitForRequest(timer_status);

if(timer_status == KRequestPending)
{
done = ETrue;
}

time += wait_interval;
timer.At(timer_status, time);
}

CleanupStack::PopAndDestroy(tel_wrapper);
CActiveScheduler::Stop();
CActiveScheduler::Install(NULL); // Uninstall the Scheduler
CleanupStack::PopAndDestroy(scheduler);
}

_LIT(KTxtEPOC32EX,"Whoops!"😉;

#ifdef __WINS__

EXPORT_C TInt InitEmulator() // mainloop function called by the emulator software
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
TRAPD( error, mainloop() ); // more initialization, then do example
__ASSERT_ALWAYS( !error, User::Panic( KTxtEPOC32EX, error ) );
delete cleanup; // destroy clean-up stack
__UHEAP_MARKEND;
//CloseSTDLIB();
User::Exit( 0 );

return KErrNone;
}

int GLDEF_C E32Dll(TDllReason)
{
return(KErrNone);
}

#else

GLDEF_C TInt E32Main() // mainloop function called by E32
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
TRAPD( error, mainloop() ); // more initialization, then do example
__ASSERT_ALWAYS( !error, User::Panic( KTxtEPOC32EX, error ) );
delete cleanup; // destroy clean-up stack
__UHEAP_MARKEND;

//CloseSTDLIB();
User::Exit( 0 );

return KErrNone; // and return
}
#endif
//----------- end of main.cpp -------------------------------------------------------------

//----------- TelephonyWrapper.h ----------------------------------------------------
#ifndef __TELEPHONYWRAPPER_H__
#define __TELEPHONYWRAPPER_H__

#include <e32base.h>
#include <etel.h>

class CTelephonyWrapper : public CActive
{
public:
CTelephonyWrapper();
~CTelephonyWrapper();
void WaitCall();

private:
RTelServer iTelServer;
RPhone iPhone;
RLine iLine;
TBuf<40> iTsyName;

void RunL();
void DoCancel();

TName iName;
};

#endif // __TELEPHONYWRAPPER_H__
//----------- End of TelephonyWrapper.h -------------------------------------------

//----------- TelephonyWrapper.cpp ----------------------------------------------------
#include <E32Math.h>
#include <f32file.h>

#include "TelephonyWrapper.h"

CTelephonyWrapper::CTelephonyWrapper() : CActive(EPriorityStandard)
{
#ifndef __WINS__

//Create a connection to the tel server
User::LeaveIfError( iTelServer.Connect() );

TInt theError;
// Find the number of phones available from the tel server
TInt numberPhones;
theError = iTelServer.EnumeratePhones(numberPhones);
if (theError)
{
iTelServer.Close();
User::LeaveIfError(theError);
}
// Check there are available phones
if (numberPhones < 1)
{
iTelServer.Close();
User::LeaveIfError(theError);
}
// Read the TSY module name
theError = iTelServer.GetTsyName(0, iTsyName);
if (theError != KErrNone)
{
iTelServer.Close();
User::LeaveIfError(theError);
}
// Load in the phone device driver
theError = iTelServer.LoadPhoneModule(iTsyName);
if (theError)
{
iTelServer.Close();
User::LeaveIfError(theError);
}

//Get info about the first available phone
RTelServer::TPhoneInfo info;
User::LeaveIfError( iTelServer.GetPhoneInfo( 0, info ) );

//Use this info to open a connection to the phone, the phone is identified by its name
User::LeaveIfError( iPhone.Open( iTelServer, info.iName ) );

//Get info about the first line from the phone
RPhone::TLineInfo lineInfo;
User::LeaveIfError( iPhone.GetLineInfo( 0, lineInfo ) );

//Use this to open a line
User::LeaveIfError( iLine.Open( iPhone, lineInfo.iName ) );

#endif

CActiveScheduler::Add(this);
}
//------------------------------------------------------------

CTelephonyWrapper::~CTelephonyWrapper()
{
#ifndef __WINS__

iLine.Close();
iPhone.Close();

User::LeaveIfError(iTelServer.UnloadPhoneModule(iTsyName));
iTelServer.Close();

#endif

Cancel();
Deque();
}
//------------------------------------------------------------

void CTelephonyWrapper::WaitCall()
{
#ifndef __WINS__

Cancel();
iLine.NotifyIncomingCall(iStatus, iName);
SetActive();

#endif
}
//------------------------------------------------------------

void CTelephonyWrapper::RunL()
{
RFs fs1;
RFile fname1;

CleanupClosePushL(fs1);
CleanupClosePushL(fname1);

fs1.Connect();
fname1.Replace( fs1, _L( "C:\\runl.txt" ), EFileWrite );
fname1.Write( _L8( "Hello world!!!\n" ) );
CleanupStack::PopAndDestroy(2); // fname1, fs1
}

void CTelephonyWrapper:: DoCancel()
{
iLine.NotifyIncomingCallCancel();
}
//----------- End of TelephonyWrapper.cpp ----------------------------------------------

I tested it by Simens SX1. Programm initialazed, but when I call, nothing happen. What must I do for receiving incoming call and enter to CTelephonyWrapper::RunL???

Sorry....i don't have a chance to go through your code thoroughlly but i don't know if it's useful trying to get the TSY module name before yourself load one so i would get rid of it and make an inquiry to the local communications database to get the appropriate module name and load it into the phone. You can find the code in the Symbian Help.
And about your decision to re-implement a scheduler for active objects....if your writing a GUI application it inherits the scheduler by default so you can use it simply.
Once you built properly the server,phone,line and used the WaitForIncomingCall() method, which by the way must be bound to the active object you're writing, you can use the other function, OpenExistingCall(), to open the call that's been initiated by the first method when completes. You have to pass to it both the line you got and the name given to the call by WaitForIncomingCall() as a return parameter.
I repeat..i'm sorry but i'm in a hurry...i'll try to answer more competently some time later.
Hope this help a little!!

Luigi

2 doc.rave:

doc.rave wrote:Sorry....i don't have a chance to go through your code thoroughlly but i don't know if it's useful trying to get the TSY module name before yourself load one so i would get rid of it and make an inquiry to the local communications database to get the appropriate module name and load it into the phone. You can find the code in the Symbian Help.

Thank you for the advise, but I know about getting the TSY module name. My code is a reductive version. I tried to get the TSY module name, but a result was the same. 😞

doc.rave wrote:
And about your decision to re-implement a scheduler for active objects....if your writing a GUI application it inherits the scheduler by default so you can use it simply.
Once you built properly the server,phone,line and used the WaitForIncomingCall() method, which by the way must be bound to the active object you're writing, you can use the other function, OpenExistingCall(), to open the call that's been initiated by the first method when completes. You have to pass to it both the line you got and the name given to the call by WaitForIncomingCall() as a return parameter.
I repeat..i'm sorry but i'm in a hurry...i'll try to answer more competently some time later.
Hope this help a little!!

Luigi

My problem is a lack of some reaction from the service when I call on the phone. Maybe I was wrong in using a scheduler by this way. The incoming call hasn't recieved by function iLine.NotifyIncomingCall(iStatus, iName) and I don't know why 😞.

You are right that it is incorrect to use ActiveScheduler this way. Why do you use Timer if you use ActiveObject? ActiveObject does it all for you. Get rid of the Timer and:

1. You don't need to create a new ActiveScheduler. Use CActiveScheduler::Add() etc. instead.

2. You need to call CActiveScheduler::Start() to start receiving Notify events.

3. Call to CActiveScheduler::Start() waits until some event calls CActiveScheduler::Stop(), so any code after CActiveScheduler::Start() can be used only for closing operations.

Refer to ActiveObjects documentation at symbian.com

Regards