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

📄 voipapp.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// 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 "VoIPApp.hpp"
#include "Common.hpp"
#include "rtcerr.h"
#include "UIManager.hpp"
#include "Debug.hpp"

#include "wininet.h"
#include "urlmon.h"

#include "CommonFunctions.hpp"
#include "VoIPCall.hpp"
#include "Settings.hpp"
#include "regext.h"

#include "NewResource.hpp"
#include "VoIPStore.h"
#include "SettingsApi.hpp"
#include "CommandAPI.hpp"


//Macro to make queryinterface nicer
#define QI(riid, interface, ppv) \
    if ((riid) == __uuidof(interface)) \
    { \
        (*ppv) = static_cast<interface *>(this); \
        AddRef(); \
        return S_OK; \
    } \

/*------------------------------------------------------------------------------
    HookswitchHotkeyState
    
    Internal enum for identifying the hook event
------------------------------------------------------------------------------*/
enum HookswitchHotkeyState
{
    e_hhsHookUp = 0,
    e_hhsHookDown,
    e_hhsSpeakerToggle
};

//key name for all the data
const WCHAR c_SIPRegKeyPath[]          = L"System\\VoIP\\SIP";

//values:
//rtc will be initialized with the DWORD stored in this value
const WCHAR c_RTCInitializationFlags[] = L"RtcInitFlags"; 

//If this DWORD is non-zero, we will enable port 5060 for incoming SIP traffic
const WCHAR c_EnablePort5060[]         = L"EnablePort5060";

//If this DWORD is non-zero, sessions will be created with the "fail on redirect" flag
const WCHAR c_FailOnRedirectEnabled[]  = L"OutgoingFailOn302";

//indicate the maximum number of calls that are allowed simultanenously
const WCHAR c_MaxNumberOfCalls[]       = L"MaxNumberOfCalls"; 

//default maximum number of calls taht are allowed simultaneously
const int   c_DefaultMaxNumberOfCalls  = 4; 

/*------------------------------------------------------------------------------
    GetSIPSetting
    
    Read a SIP setting from the registry
    
    Parameters:
        pSettingName: The setting name
    
    Returns (DWORD): Value from registry or 0 if the value doesn't exist 
------------------------------------------------------------------------------*/
DWORD   GetSIPSetting(
    __in const WCHAR*   pSettingName
    )
{
    ASSERT(pSettingName);
    
    DWORD Value = 0;

    RegistryGetDWORD(
        HKEY_LOCAL_MACHINE, 
        c_SIPRegKeyPath, 
        pSettingName, 
        &Value
        ); 

    return Value;
}

/*------------------------------------------------------------------------------
    GetRTCInitializationFlags
    
    Get the flag value to initialize RTC with - please see the RTC initialization
    flags in the documentation. 

    - Also does a quick check to make sure the values are valid...
------------------------------------------------------------------------------*/
LONG    GetRTCInitializationFlags()
{
    DWORD   RegValue = GetSIPSetting(c_RTCInitializationFlags);

    //if prefer_static_port is set, symmetric signalling has to be set as well
    if (RegValue & RTCIF_PREFER_STATIC_PORT_FOR_SYMMETRIC_UDP)
    {
        RegValue |= RTCIF_ENABLE_SYMMETRIC_UDP_SIGNALING;
    }

    return static_cast<LONG>(RegValue);
}

/*------------------------------------------------------------------------------
    GetRTCListenMode
    
    Gets the RTC "listen mode" (based on registry settings),
    which determine what ports to open for incoming SIP traffic
------------------------------------------------------------------------------*/
RTC_LISTEN_MODE GetRTCListenMode()
{
    return (GetSIPSetting(c_EnablePort5060) ? RTCLM_BOTH : RTCLM_DYNAMIC);    
}

/*------------------------------------------------------------------------------
    GetRTCCreateSessionFlags
    
    Get the flags passed into the CreateSession API taking
    into account OEM settings from the registry
------------------------------------------------------------------------------*/
LONG GetRTCCreateSessionFlags()
{
    return (GetSIPSetting(c_FailOnRedirectEnabled) ? RTCCS_FAIL_ON_REDIRECT : 0);
}


/*------------------------------------------------------------------------------
    GetMaxNumberOfCalls
    
    Get the max number of calls that are allowed simutanously
------------------------------------------------------------------------------*/
unsigned int GetMaxNumberOfCalls()
{
    DWORD MaxNumber = 0; 
    
    HRESULT hr = RegistryGetDWORD(
                    HKEY_LOCAL_MACHINE, 
                    c_SIPRegKeyPath, 
                    c_MaxNumberOfCalls, 
                    &MaxNumber
                    ); 
    if (FAILED(hr))
    {
        return c_DefaultMaxNumberOfCalls; 
    }

    if (MaxNumber < 2)
    {
        PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"The max number of calls specified in registry is less than 2!")); 
        return c_DefaultMaxNumberOfCalls; 
    }
    
    return MaxNumber; 
}
/*------------------------------------------------------------------------------
    IsMuted

    Helper function to determine the current mute status of RTC client
------------------------------------------------------------------------------*/
inline 
bool IsMuted(
    __in IRTCClient* pClient
    )
{
    if (pClient == NULL)
    {
        return false; 
    }
    
    VARIANT_BOOL IsRTCMuted = VARIANT_FALSE;
    pClient->get_AudioMuted(RTCAD_MICROPHONE, &IsRTCMuted);

    return (IsRTCMuted == VARIANT_TRUE); 
    
}


bool ShouldBeVisible(
        const WCHAR*    c_pCommandLine
        )
{
    static const WCHAR sc_Parameter[] = L"-n"; 

    if (c_pCommandLine == NULL || 
        c_pCommandLine[0] == NULL)
    {
        return true; 
    }

    if (PhoneAppUtilities_t::InvStrCmpNI(
                            c_pCommandLine, 
                            sc_Parameter, 
                            ARRAYSIZE(sc_Parameter)
                            )== 0)
    {
        return false; 
    }

    return true; 

}
        

/*------------------------------------------------------------------------------
    VoIPApp_t::VoIPApp_t
    
    Constructor for the app class
------------------------------------------------------------------------------*/
VoIPApp_t::VoIPApp_t()
{
    m_AudioMode                 = e_vamIdle;
    m_HookSwitchIsUp            = false;
    m_fAlreadyRefreshed         = TRUE;
    m_vkLastKeyPressed          = -1;
    m_fWaitingForPressAndHold   = FALSE;
    
    m_PlayingProgressTone       = false;
    m_DoNotPlayDialTone         = false;
    m_OffHookByMakingCall       = false; 

    DWORD dwTick = GetTickCount();
    m_tickLastKeydown           = dwTick;
    m_tickLastUserAction        = dwTick;

    //intialize the newly added varaibles for Yamazaki
    m_cpRTCClient               = NULL; 
    m_cpConnectionPt            = NULL;     
    m_NotificationWindow        = NULL; 
    m_ConnectionPtCookie        = 0; 
    m_MaxNumberOfCalls          = c_DefaultMaxNumberOfCalls; 
    m_PendingAuthAction         = ActionInvalid;
}

VoIPApp_t::~VoIPApp_t()
{

    if (m_NotificationWindow)
    {
        DestroyWindow(m_NotificationWindow); 
        m_NotificationWindow = NULL; 
    }

    UnregisterClass(
        WNDCLASS_PHONEAPP,
        GlobalData_t::s_ModuleInstance
        ); 

    ASSERT(m_CallList.size() == 0); 

    if (m_cpRTCClient != NULL)
    {
        ASSERT(0); 
        Uninitialize(); 
    }

}

HRESULT 
VoIPApp_t::ForegroundExistingApp(
    void
    )
{
    if (IsOffHook())
    {
        // The phone is off-hook, simulate a hook mode change
        // to force an update of the UI
        m_UIManager.OnHookModeChange(false);
    }
    return S_OK;
}

// IUnknown implementation
ULONG VoIPApp_t::AddRef()
{ 
    return ++m_cRefs; 
}

ULONG VoIPApp_t::Release()    
{ 
    //not a real COM object - release does not delete the object
    m_cRefs--; 
    ASSERT(m_cRefs >= 0); 
    return m_cRefs; 
}


HRESULT VoIPApp_t::QueryInterface(
    REFIID riid, 
    VOID** ppvObj
    )
{
    if (! ppvObj)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }

    if (riid == IID_IUnknown)
    {
        (*ppvObj) = static_cast<IUnknown*>(static_cast<IRTCEventNotification*>(this));
        AddRef();
        return S_OK;
    }
    
    QI(riid, IRTCEventNotification, ppvObj)

    return E_NOINTERFACE;
}        



/*------------------------------------------------------------------------------
    VoIPApp_t::Shutdown
    
    Begins the shutdown process for the application
    
    Returns (HRESULT): 
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::Shutdown()
{
    //uninitialize the voip manager - if we can't pretend the uninitialization already happened
    PostMessage(NULL, WM_CLOSE, 0, 0);
    return S_OK;
}

/*------------------------------------------------------------------------------
    VoIPApp_t::EnsureOffHook
    
    Ensures that the phone is off hook right now
    if the phone is not offhook - simulates a speaker-phone press
    
    Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::EnsureOffHook()
{
    //if we are already offhook, do nothing
    if (m_AudioMode != e_vamIdle)
    {
        return S_FALSE;
    }

    //otherwise simulate the speaker toggle being pressed
    return OnHookModeChange(HotKeys_t::vkSpeaker, FALSE); //FALSE means KEYDOWN event
}

/*------------------------------------------------------------------------------
    VoIPApp_t::PlayProgressToneForDisconnectedCall
    
    If a call disconnects for a non-normal reason (e.g. busy, bad number etc), 
    play the appropriate progress tone for the call
    
    Parameters:
        pCall: The call that was disconnected
        pfPlayingTone: indicate if it is playing any tone for disconnect or not
    
    Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT 
VoIPApp_t::PlayProgressToneForDisconnectedCall(
    Call_t* pCall, 
    bool*   pPlayingTone
    )
{
    if (pCall == NULL || pPlayingTone == NULL)
    {
        return E_INVALIDARG; 
    }
    
    HRESULT hr = S_OK;
    DWORD   NetworkStatus = pCall->GetNetworkStatus(); 
    AudioManager_t::ProgressToneType_e ProgressToneType = AudioManager_t::ProgressToneInvalid; 
    
    if (FAILED(NetworkStatus))
    {
        switch (NetworkStatus)
        {
        case RTC_E_STATUS_CLIENT_BUSY_HERE:
        case RTC_E_STATUS_GLOBAL_BUSY_EVERYWHERE:
            ProgressToneType = AudioManager_t::ProgressToneClientBusy; 
            break;

        default:
            ProgressToneType = AudioManager_t::ProgressToneReorder; 
            break;
        }

        hr = PlayProgressTone(ProgressToneType); 
        *pPlayingTone = true;
    }
    else
    {
        hr = StopActiveTone();
        *pPlayingTone = false; 
    }

    return hr;
}

/*------------------------------------------------------------------------------
    VoIPApp_t::InitializeHookState
    
    Initializes the internal state of the hookswitch on startup
    
    Returns (HRESULT): 
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::InitializeHookState()
{
    ASSERT(m_AudioMode == e_vamIdle);

    HRESULT hr = S_FALSE;
    if (GetAsyncKeyState(HotKeys_t::GetHotKey(HotKeys_t::vkHookSwitch)) & 0x80)
    {
        m_HookSwitchIsUp = true;
        //Simulate a press 
        hr = OnHookModeChange(HotKeys_t::vkHookSwitch, FALSE); //false means key down
    }
    else
    {
        m_HookSwitchIsUp = false;
    }

    return hr;
}

/*------------------------------------------------------------------------------
    VoIPApp_t::RespondToHotKey
    
    Handle a hotkey press
------------------------------------------------------------------------------*/
LRESULT VoIPApp_t::RespondToHotKey(
    INT  HotkeyId,

⌨️ 快捷键说明

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