⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 voipcall.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"received a RTCSessionReferStatusChangeEvent w/ RTCSRS_DONE"));                        
        KillTimer(&m_TransferDoneTimerId); 
        return End(); 

    default:
        break;
    }

    return S_OK;

}

/*------------------------------------------------------------------------------
    VoIPGroup_t::OnRTCSessionReferredEvent

    Handle a notification from the phone canvas object that there is a Refered event
    comming with this session

    this notification is handled by the receiver in transfer scenario
------------------------------------------------------------------------------*/
HRESULT 
VoIPCall_t::OnRTCSessionReferredEvent(
    IRTCSessionReferredEvent*          pEvent
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

    //validate the input
    if (!pEvent)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }

    return DoPhoneVerb(PH_VERB_HOLD); 
}


/*------------------------------------------------------------------------------
    VoIPCall_t::OnParticipantStateChangeEvent

    Updates internal state based on an RTCE_PARTICIPANT_STATE_CHANGE event
------------------------------------------------------------------------------*/
HRESULT 
VoIPCall_t::OnRTCParticipantStateChangeEvent(
    IRTCParticipantStateChangeEvent*    pEvent
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

    if (! pEvent)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }

    RTC_PARTICIPANT_STATE   ParticipantState  = RTCPS_IDLE;

    //get the new state from the event
    HRESULT hr = pEvent->get_State(&ParticipantState);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not get the participant state from the event! [Hr = 0x%x]", hr));
        return hr;
    }

    switch (ParticipantState)
    {
    case RTCPS_CONNECTED:
        //if this is the first connected event we should record the new connected time
        if (!IsValidTime(&m_StartTime))
        {
             GetLocalTime(&m_StartTime); 
        }
        else
        {
            hr = S_FALSE;
        }
        break;

    case RTCPS_DISCONNECTED:
        
        UpdateDisconnectReason(pEvent);

        LogCallIfNecessary(); 

        break;

    default:
        hr = S_FALSE;
        break;
    }

    return hr;
}

/*------------------------------------------------------------------------------
    VoIPCall_t::StartRingbackTone
    
    Start playing the ringback tone after a small timeout
------------------------------------------------------------------------------*/
void 
VoIPCall_t::StartRingbackTone()
{
    if (m_StartRingbackTimerId)
    {
        return;
    }

    //start a timer for a short while before actually playing the ringback tone - 
    //we want to prevent unnecessary playback when we get a 180 then a connect/disconnect/update
    //and have to stop the ringback. 
    GetApp()->GetTimers().AddTimer(
        sc_RingbackStartTimeout,
        this,
        &m_StartRingbackTimerId
        );
    
    return;
}
/*------------------------------------------------------------------------------
    VoIPCall_t::StopRingbackTone
    
    If we are currently playing the ringback tone, stop it!
------------------------------------------------------------------------------*/
void 
VoIPCall_t::StopRingbackTone()
{
    KillTimer(&m_StartRingbackTimerId);
    
    if (m_PlayingRingbackTone)
    {
        GetApp()->StopActiveTone(); 
        m_PlayingRingbackTone = false;
    }
}

/*------------------------------------------------------------------------------
    VoIPCall_t::KillTimer
    
    Terminates a timer (if the timer is still active)

    Parameters:
        pTimerId    : The pointer to a timer identifier 
------------------------------------------------------------------------------*/
void 
VoIPCall_t::KillTimer(UINT* pTimerId)
{
    if (pTimerId == NULL)
    {
        return; 
    }

    if ((*pTimerId != 0) && (GetApp() != NULL))
    {
        GetApp()->GetTimers().RemoveTimer(*pTimerId); 
        *pTimerId = 0; 
    }

    return; 
}

/*------------------------------------------------------------------------------
    VoIPCall_t::OnTimerExpires
    
    Handles our inactivity timer expiring - indicating it is time to forward
    this call
    
    Parameters:
        : The identifier of the timer which has expired
------------------------------------------------------------------------------*/
void 
VoIPCall_t::OnTimerExpires(
    UINT    TimerId
    )
{
    if (TimerId == 0)
    {
        return;
    }

    //if the ringback timer expires, we play the ringback tone
    if (TimerId == m_StartRingbackTimerId)
    {
        GetApp()->PlayProgressTone(AudioManager_t::ProgressToneRingback); 
        m_PlayingRingbackTone = true;

        KillTimer(&m_StartRingbackTimerId);
    }
    else if (TimerId == m_TransferDoneTimerId)
    {
        KillTimer(&m_TransferDoneTimerId); 
        End(); 
    }
        
    return;
}


HRESULT 
VoIPCall_t::GetURI(BSTR* pURI)
{
    if (m_cpRTCParticipant == NULL)
    {
        return E_FAIL; 
    }

    return m_cpRTCParticipant->get_UserURI(pURI); 
    
}


HRESULT             
VoIPCall_t::GetDuration(
    SYSTEMTIME* pDuration
    )
{
    if (pDuration == NULL)
    {
        return E_INVALIDARG; 
    }

    //initialize the duration structure to 0
    memset(pDuration, 0, sizeof(SYSTEMTIME)); 
    
    if (!IsValidTime(&m_StartTime))
    {
        //we have not gotten the RTCPS_CONNECTED event yet, return S_FALSE
        return S_FALSE; 
    }

    GetLocalTime(&m_EndTime); 

    ULONGLONG ullStartTime; 
    ULONGLONG ullEndTime; 

    HRESULT hr = GetSystemTimeAsULL(&m_StartTime, &ullStartTime); 
    if (FAILED(hr))
    {
        return hr; 
    }

    hr = GetSystemTimeAsULL(&m_EndTime, &ullEndTime); 
    if (FAILED(hr))
    {
        return hr; 
    }

    return GetULLAsSystemTime(
            ullEndTime - ullStartTime, 
            pDuration
            ); 

}


HRESULT
VoIPCall_t::DoVerbTransfer(
        VPARAM Parameter
        )
{
    if (Parameter == NULL)
    {
        return E_INVALIDARG; 
    }

    if (m_cpRTCSession == NULL)
    {
        return E_UNEXPECTED; 
    }

    WCHAR* pTransferToURI = reinterpret_cast<WCHAR*>(Parameter); 
    ce::auto_bstr TransferToURI = SysAllocString(pTransferToURI); 

    CComPtr<IRTCSessionCallControl> cpSessionCallControl; 
    HRESULT hr = m_cpRTCSession->QueryInterface(
                                    IID_IRTCSessionCallControl,
                                    (void **)&cpSessionCallControl
                                    ); 
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to query interface for IRTCSessionCallControl -- error code = 0x%x", hr)); 
        return hr; 
    }
    
    hr = cpSessionCallControl->Refer(
                                TransferToURI, 
                                TransferToURI
                                ); 
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at refering -- error code = 0x%x", hr)); 
        return hr; 
    }

    return hr; 
}


HRESULT
VoIPCall_t::SetInfoAboutBeingTransferred(
    IRTCSessionReferredEvent*  pRTCSessionReferredEvent, 
    Call_t*                    pReferringCall
    )
{
    if ((pRTCSessionReferredEvent == NULL) || (pReferringCall == NULL))
    {
        return E_INVALIDARG; 
    }

    if (IsBeingTransferred())
    {
        return E_FAIL; 
    }

    m_cpRTCSessionReferredEvent = pRTCSessionReferredEvent; 
    m_cpReferringCall           = pReferringCall; 

    return S_OK; 
}


HRESULT
VoIPCall_t::StateChangeWhileBeingTransferred(
    RTC_SESSION_STATE NewSessionState
    )
{
    HRESULT hr = S_OK; 
    
    switch(NewSessionState)
    {
    case RTCSS_CONNECTED: 
        //transfer: receiver notifies the initiator that refer is successful
        hr = m_cpRTCSessionReferredEvent->SetReferredSessionState(RTCSS_CONNECTED);
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at setting referred session state -- error code = 0x%x", hr));
            return hr;
        }

        ClearInfoAboutBeingTransferred();
        return S_OK;
        
    case RTCSS_DISCONNECTED: 
        //if this is still being transferred
        //transfer: receiver notifies the refer-er that refer is failed, maybe caused by the target rejects the callneeds to check if the current session is still being transferred
        hr = m_cpRTCSessionReferredEvent->SetReferredSessionState(RTCSS_DISCONNECTED);
        if (FAILED(hr))
        {
            //even if it fails, still keep going
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at setting referred session state -- error code = 0x%x", hr));
        }

        //unhold the session with refer-er
        hr = m_cpReferringCall->DoPhoneVerb(PH_VERB_UNHOLD);
        if (FAILED(hr))
        {
            //even if it fails, still keep going
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at unholding session -- error code = 0x%x", hr));
        }

        ClearInfoAboutBeingTransferred();

        return hr;

    default: 
        break;         
    }

    return hr; 
}

void
VoIPCall_t::UpdateNewLoggedCall(
    VoIPCallType CallType
    )
{
    HRESULT hr;    

    switch (CallType)
    {
    case e_vctIncoming:
        hr = PHSetValue(phsIncomingCalls, 1);
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at writting new incoming call count to regsitry, hr = 0x%x", hr)); 
        }
        break;
        
    case e_vctOutgoing: 
        hr = PHSetValue(phsOutgoingCalls, 1);
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at writting new outgoing call count to regsitry, hr = 0x%x", hr)); 
        }
        break;
        
    case e_vctMissed:
        hr = PHSetValue(phsMissedCalls, 1);
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at writting new missed call count to regsitry, hr = 0x%x", hr)); 
        }
        break;

    default:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Invalid call type specified.")); 
    }
    return; 
}

/*------------------------------------------------------------------------------
    VoIPCall_t::LogCall
    
    Log call to database
------------------------------------------------------------------------------*/
void
VoIPCall_t::LogCallIfNecessary(
    void
    )
{
    if (m_IsLogged)
    {
        //return if the call is already been logged
        return;         
    }
    
    GetLocalTime(&m_EndTime); 
    if (!IsValidTime(&m_StartTime))
    {
        //if we don't have valid start time, it means we either rejected the call or the call was missed
        //we should set the start time as the same as end time for both cases
        memcpy(&m_StartTime, &m_EndTime, sizeof(SYSTEMTIME)); 
    }

    if (m_CouldBeMissed && m_CallType == e_vctIncoming)
    {
        m_CallType = e_vctMissed; 
    }

    GetApp()->GetDatabase().AddToCallLog(
                                GetDisplayNumber(), 
                                GetDisplayName(), 
                                m_bstrName, 
                                m_CallType, 
                                m_StartTime, 
                                m_EndTime
                                );
    
    UpdateNewLoggedCall(m_CallType);

    //set the flag to indicate the call is already logged
    m_IsLogged = true; 

    return; 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -