Symbian開發中實現撥打電話功能

#ifndef _DIALENGINE_H_
#define _DIALENGINE_H_

// 注:這個類的使用需要能力NetworkServices和NetworkControl

#include <etel.h> // need etel.lib

class MPhoneCallClientObserver
{
public:
    virtual void HandleCallHungUpL() = 0;
};

class CDialEngine: public CActive
{
public:
    static CDialEngine* NewL(MPhoneCallClientObserver& aObserver);
    ~CDialEngine();

public:
    // CActive
    virtual void RunL();
    virtual void DoCancel();

public:
    void MakeCallL(const TDesC& aNumber);

private:
    // the state of this object governs what happens when the
    // StartL() / Stop() / RunL() / DoCancel() functions are called.
    enum TState
    {
        ENoState, EDialling, EWatching
    };

private:
    CDialEngine(MPhoneCallClientObserver& aObserver);
    void ConstructL();

private:
    void StartL();
    void Stop();
    void InitCallServerL();
    void TelephonyCleanup();

private:
    MPhoneCallClientObserver& iObserver;

    RTelServer iServer;
    RPhone iPhone;
    RLine iLine;
    RCall iCall;

    RCall::TStatus iCallStatus;
    TState iState;
    TPtrC iNumber;
};

#endif // _DIALENGINE_H_

#include "DialEngine.h"

_LIT(KTsyName,"phonetsy.tsy");

CDialEngine::CDialEngine(MPhoneCallClientObserver& aObserver) :
    CActive(EPriorityNormal), iObserver(aObserver), iState(ENoState)
{
}

CDialEngine::~CDialEngine()
{
    Cancel();
    TelephonyCleanup();
}

CDialEngine* CDialEngine::NewL(MPhoneCallClientObserver& aObserver)
{
    CDialEngine* self = new (ELeave) CDialEngine(aObserver);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
}

void CDialEngine::ConstructL()
{
    CActiveScheduler::Add(this);
    InitCallServerL();
}

void CDialEngine::MakeCallL(const TDesC& aNumber)
{
    iNumber.Set(aNumber);
    
    iState = EDialling;
    StartL();
}

void CDialEngine::InitCallServerL()
{
    iServer.Connect();
    iServer.LoadPhoneModule(KTsyName);

    //Find the number of phones available from the tel server
    TInt numberPhones;
    User::LeaveIfError(iServer.EnumeratePhones(numberPhones));

    //Check there are available phones
    if (numberPhones < 1) {
        User::Leave(KErrNotFound);
    }
    //Get info about the first available phone
    RTelServer::TPhoneInfo info;
    User::LeaveIfError(iServer.GetPhoneInfo(0, info));

    //Use this info to open a connection to the phone, the phone is identified by its name
    User::LeaveIfError(iPhone.Open(iServer, 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));
    
    User::LeaveIfError(iCall.OpenNewCall(iLine));
}

void CDialEngine::StartL()
{
    switch (iState) {
    case ENoState:
        return;
    case EDialling:
    {
        iCall.Dial(iStatus, iNumber);
        break;
    }
    case EWatching:
        iCall.NotifyStatusChange(iStatus, iCallStatus);
        break;
    }
    SetActive();
}

void CDialEngine::RunL()
{
    // if the caller hangs up, then we will get KErrGeneral error here
    if (iState == EDialling && iStatus.Int() == KErrGeneral) {
        Stop();
        iObserver.HandleCallHungUpL();
        return;
    }

    if (iStatus.Int() != KErrNone)
        return;

    switch (iState) {
    case EDialling:
        iState = EWatching;
        StartL();
        break;

    case EWatching:
        User::LeaveIfError(iCall.GetStatus(iCallStatus));
        if (iCallStatus == RCall::EStatusHangingUp || iCallStatus == RCall::EStatusIdle) {
            Stop();
            iObserver.HandleCallHungUpL();
        }
        else {
            StartL();
        }
        break;

    default:
        break;
    }
}

void CDialEngine::DoCancel()
{
    Stop();
}

void CDialEngine::Stop()
{
    switch (iState) {
    case ENoState:
        break;
    case EDialling:
        iCall.HangUp();
        break;
    case EWatching:
        iCall.NotifyStatusChangeCancel();
        break;
    }
    iState = ENoState;
}

void CDialEngine::TelephonyCleanup()
{
    iCall.Close();
    iLine.Close();
    iPhone.Close();
    iServer.Close();
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章