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

📄 voipcall.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "VoIPCall.hpp"
#include "CommonFunctions.hpp"
#include <auto_xxx.hxx>         //for auto_bstr etc.
#include <rtcerr.h>             //for RTC error codes
#include "DialEngine.hpp"
#include "Debug.hpp"
#include "VoIPApp.hpp"
#include "SettingsApi.hpp"

bool
IsValidTime(
    const SYSTEMTIME* pTime 
    )
{
    if (pTime == NULL)
    {
        return false; 
    }

    FILETIME FileTime = {0}; 

    if (!SystemTimeToFileTime(pTime, &FileTime))
    {
        return false; 
    }

    if (FileTime.dwHighDateTime == 0 && FileTime.dwLowDateTime == 0)
    {
        return false; 
    }

    return true; 
}

/*------------------------------------------------------------------------------
    GetULLAsSystemTime

    Utility function that gets the current system time as an unsigned long long
------------------------------------------------------------------------------*/
HRESULT 
GetULLAsSystemTime(
    ULONGLONG           ull, 
    __out SYSTEMTIME*   pSystemTime
    )
{
    if (pSystemTime == NULL)
    {
        return E_INVALIDARG;
    }

    ull /= 10000; // convert to ms -- 1 ns is 10^6 ms so 100 ns is 10^4 ms
    
    pSystemTime->wMilliseconds = (WORD)(ull % 1000);
    ull /= 1000;

    pSystemTime->wSecond       = (WORD)(ull % 60);
    ull /= 60;

    pSystemTime->wMinute       = (WORD)(ull % 60);
    ull /= 60;

    pSystemTime->wHour         = (WORD)(ull % 24);
    ull /= 24;

    pSystemTime->wDay          = (WORD)ull;

    pSystemTime->wYear         = 0; 
    pSystemTime->wDayOfWeek    = 0; 
    pSystemTime->wMonth        = 0;
    
    return S_OK;        
}
/*------------------------------------------------------------------------------
    GetSystemTimeAsULL

    Utility function that gets the current system time as an unsigned long long
------------------------------------------------------------------------------*/
HRESULT 
GetSystemTimeAsULL(
    const SYSTEMTIME*   pSystemTime, 
    __out ULONGLONG*    pDest
    )
{
    if (pDest == NULL || pSystemTime == NULL)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }

    FILETIME   FileTime = {0};

    if (! SystemTimeToFileTime(pSystemTime, &FileTime))
    {
        ASSERT(FALSE);
        return CommonUtilities_t::GetErrorFromWin32();
    }

    //shift the high time over to the upper 32 bits and OR in the lower bits
   *pDest = (static_cast<ULONGLONG>(FileTime.dwHighDateTime) << 32) | FileTime.dwLowDateTime;
    return S_OK;
}

const UINT VoIPCall_t::sc_RingbackStartTimeout  = 150;
const UINT VoIPCall_t::sc_TransferDoneTimeout   = 10 * 1000; 

/*------------------------------------------------------------------------------
    VoIPCall_t::CreateNewCall

    Static method used for creating and initializing a new call object

    Parameters:
        IsOutgoingCall: Is this an outgoing call?
        pFriendlyNumber: (optional) Friendly number string if it is already known before we create the call. e.g outgoing call 
        pFriendlyName: (optional) Friendly name string if it is already known before we create the call. e.g. PHMakePhoneCall is called
        pRTCSession: pointer to a valid RTC Session object
        ppCall:  OUT - the returned call

    Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
/* static */ HRESULT VoIPCall_t::CreateNewCall(
    bool            IsOutgoingCall, 
    const WCHAR*    pFriendlyNumber, 
    const WCHAR*    pFriendlyName, 
    IRTCSession*    pRTCSession,
    Call_t**        ppCall
    )
{
    //validate parameters
    if (ppCall == NULL || pRTCSession == NULL)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }


    VoIPCall_t* pOutCall = new VoIPCall_t();
    if (! pOutCall)
    {
        return E_OUTOFMEMORY;
    }

    HRESULT hr = pOutCall->Initialize(
                            IsOutgoingCall, 
                            pFriendlyNumber, 
                            pFriendlyName, 
                            pRTCSession
                            );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to initialize the call - error: 0x%x", hr));

        //cleanup
        //
        pOutCall->Release();
       *ppCall = NULL;

        return hr;
    }

    *ppCall = static_cast<Call_t*>(pOutCall);
    return S_OK;
}


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

    Ctor
------------------------------------------------------------------------------*/
VoIPCall_t::VoIPCall_t()
{
    TRACE(ZONE_PHONEAPP_CTOR);
    m_CouldBeMissed             = true;
    m_IsLogged                  = false; 
    
    m_PlayingRingbackTone       = false;
    m_StartRingbackTimerId      = 0;

    m_cpRTCParticipant          = NULL;
    m_cpRTCSession              = NULL;
    m_cpRTCSessionReferredEvent = NULL; 
    m_cpReferringCall           = NULL; 

}

/*------------------------------------------------------------------------------
    VoIPCall_t::~VoIPCall_t

    Dtor
------------------------------------------------------------------------------*/
VoIPCall_t::~VoIPCall_t()
{
    TRACE(ZONE_PHONEAPP_CTOR);

    //terminate the session once this object is to be destroyed
    //since we are not tracking it
    if ((m_cpRTCSession) && (GetCallStatus() != RTCSS_DISCONNECTED))
    {
        m_cpRTCSession->Terminate(RTCTR_SHUTDOWN);
    }

    StopRingbackTone();

    m_cpRTCParticipant          = NULL;
    m_cpRTCSession              = NULL;
    m_cpRTCSessionReferredEvent = NULL; 
    m_cpReferringCall           = NULL; 
    
}

/*------------------------------------------------------------------------------
    VoIPCall_t::Initialize

    Initializes this object from an existing IRTCSession

    Parameters:
        IsOutgoingCall: Is this an outgoing call?
        pFriendlyNumber: (optional) Friendly number string if it is already known before we create the call. e.g outgoing call 
        pFriendlyName: (optional) Friendly name string if it is already known before we create the call. e.g. PHMakePhoneCall is called
        pRTCSession: pointer to a valid RTC Session object

    Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT VoIPCall_t::Initialize(
    bool            IsOutgoingCall,
    const WCHAR*    pFriendlyNumber, 
    const WCHAR*    pFriendlyName, 
    IRTCSession*    pRTCSession
    )
{
    if (pRTCSession == NULL)
    {
        return E_INVALIDARG; 
    }
    
    m_CallType = IsOutgoingCall ? e_vctOutgoing : e_vctIncoming;

    //set the new session variable
    m_cpRTCSession  = pRTCSession;

    CComPtr<IRTCEnumParticipants> cpEnumParticipants;
    HRESULT hr = m_cpRTCSession->EnumerateParticipants(
                                    &cpEnumParticipants
                                    );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get participant list from the session - hr = 0x%x", hr));
        return hr;
    }

    CComPtr<IRTCParticipant>    cpParticipant;
    hr = cpEnumParticipants->Next(1, &m_cpRTCParticipant, NULL);
    if (hr != S_OK)
    {
        PHONEAPP_DEBUGMSG(hr != S_FALSE && ZONE_PHONEAPP_ERROR, (L"Failed to get the next participant from the session - hr = 0x%x", hr));
        return hr;
    }

    hr = m_cpRTCParticipant->get_UserURI(&m_bstrURI); 
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at getting the remove URI, hr = 0x%x", hr));     
        return hr; 
    }

    //use the specified friendly number first if it exists
    if (pFriendlyNumber != NULL &&
        pFriendlyNumber[0] != L'\0')
    {
        m_bstrFriendlyNumber = SysAllocString(pFriendlyNumber); 
        if (m_bstrFriendlyNumber == NULL)
        {
            return E_OUTOFMEMORY; 
        }
    }
    else
    {
        //otherwise, get it by converting from URI
        hr = GetApp()->GetDialEngine().GetPhoneNumberToDisplay(
                                            m_bstrURI, 
                                            -1, 
                                            NULL,                   //use active profile
                                            &m_bstrFriendlyNumber
                                            ); 
    }
    
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at formating the remote URI, hr = 0x%x", hr)); 
        return hr; 
    }

    hr = m_cpRTCParticipant->get_Name(&m_bstrName); 
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at gettting name from network, hr = 0x%x", hr)); 
    }

    //use the specified friendly name first if it exists
    if (pFriendlyName != NULL &&
        pFriendlyName[0] != L'\0')
    {
        m_bstrFriendlyName = SysAllocString(pFriendlyName); 
        if (m_bstrFriendlyName == NULL)
        {
            return E_OUTOFMEMORY; 
        }

    }

    //get the caller information from database
    hr = GetApp()->GetDatabase().GetCallerInfo(
                                    m_bstrFriendlyNumber, 
                                    (m_bstrFriendlyName != NULL && m_bstrFriendlyName[0] != L'\0') ? NULL : &m_bstrFriendlyName, 
                                    &m_bstrRingTonePath, 
                                    &m_IsBlocked
                                    ); 
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at gettting information from database, hr = 0x%x", hr));         
    }


    //if we still don't have a good caller id, try the POOM
    if (m_bstrFriendlyName == NULL ||
        m_bstrFriendlyName[0] == L'\0')
    {

        hr = GetApp()->GetPoom().GetCallerName(
                                    m_bstrFriendlyNumber, 
                                    &m_bstrFriendlyName
                                    ); 
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at getting caller id from Poom, hr = 0x%x", hr)); 
        }
    }

    return S_OK;

}


/*------------------------------------------------------------------------------
    VoIPCall_t::ForceDestroy
    
    Delete this object and null out RTC pointers
------------------------------------------------------------------------------*/
void 
VoIPCall_t::ForceDestroy(
    void
    )
{
    PhoneAppUtilities_t::NullOutCOMPtr<IRTCParticipant>(&m_cpRTCParticipant);
    PhoneAppUtilities_t::NullOutCOMPtr<IRTCSession>(&m_cpRTCSession);
    delete this;
    return;
}

/*------------------------------------------------------------------------------
    VoIPCall_t::DoPhoneVerb

    Perform an action for the phone application.
------------------------------------------------------------------------------*/
HRESULT 
VoIPCall_t::DoPhoneVerb(
    PH_VERB Verb,
    VPARAM  Parameter
    )
{
    HRESULT hr = S_OK;

    switch (Verb)
    {
    case PH_VERB_HOLD:
    case PH_VERB_UNHOLD:
        hr = DoVerbHoldUnhold(Verb);
        break;

    case PH_VERB_ACCEPT_INCOMING:
    case PH_VERB_REJECT_INCOMING:
        hr = DoVerbAcceptRejectIncomingCall(Verb);
        break;

    case PH_VERB_TALK:
        hr = DoVerbTalk();
        break;

    case PH_VERB_END:
        hr = DoVerbEnd();
        break;

    case PH_VERB_TRANSFER:
        hr = DoVerbTransfer(Parameter); 
        break;

    default:
        hr = E_NOTIMPL;
        break;
    }

    return hr;
}

/*------------------------------------------------------------------------------
    VoIPCall_t::Contains

    Overloaded Comparison operator - compares internal participant to specified
    participant
------------------------------------------------------------------------------*/
bool 
VoIPCall_t::Contains(
    IRTCParticipant* pParticipant
    )
{
    return PhoneAppUtilities_t::AreCOMPointersEqual<IRTCParticipant>(
        static_cast<IRTCParticipant*>(m_cpRTCParticipant),
        pParticipant
        );
}

/*------------------------------------------------------------------------------
    VoIPCall_t::operator==

    Overloaded comparison operator - compares internal session to specified
    session
------------------------------------------------------------------------------*/
bool 
VoIPCall_t::Contains(
    IRTCSession* pSession
    )
{
    return PhoneAppUtilities_t::AreCOMPointersEqual<IRTCSession>(
        static_cast<IRTCSession*>(m_cpRTCSession),
        pSession
        );
}

/*------------------------------------------------------------------------------
    VoIPCall_t::UpdateDisconnectReason

    When the call disconnects, this retreives the reason why the call disconnects
    to help determine if the call was terminated for strange reasons (e.g. busy etc)
------------------------------------------------------------------------------*/
HRESULT 
VoIPCall_t::UpdateDisconnectReason(

⌨️ 快捷键说明

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