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

📄 proxyservices.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    if (pCollection->m_cpEnabledProfile != NULL)
    {
        hr = UnregisterClientFromSIPProxy(pCollection);

        if (SUCCEEDED(hr) && pCollection->m_Unregistering)
        {
            //successfully started the unregistration - we need to wait for
            //that to finish before continuing
            return S_OK;
        }

        //that failed - we should simply NULL out the profile and continue
        pCollection->m_cpEnabledProfile = NULL;
    }

    //ensure we have a profile to enable
    if (pCollection->m_cpToBeEnabledProfile == NULL)
    {
        return E_FAIL;
    }

    //enable the to-be-enabled profile
    CComPtr<IRTCClientProvisioning> cpProvisioning;
    CComPtr<IRTCClient>             cpClient;

    cpClient = GetRTCClientPointer();
    if (cpClient == NULL)
    {
        hr = E_FAIL;
        goto error;
    }

    hr = GetRTCClientPointer()->QueryInterface(
        IID_IRTCClientProvisioning,
        reinterpret_cast<VOID**>(&cpProvisioning)
        );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"QueryInterface failed to get IRTCClientProvisioning [0x%x]", hr));
        ASSERT(FALSE);

        goto error;
    }

    //Enable the profile
    hr = cpProvisioning->EnableProfile(
        pCollection->m_cpToBeEnabledProfile,
        RTCRF_REGISTER_INVITE_SESSIONS
        );

    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"EnableProfile failed - [0x%x]", hr));
        goto error;
    }

    //Set the profile as the "enabled" profile
    pCollection->m_cpEnabledProfile     = pCollection->m_cpToBeEnabledProfile;
    pCollection->m_cpToBeEnabledProfile = NULL;

    return S_OK;

error:
    //everything failed - clear out smart pointers
    pCollection->m_cpEnabledProfile     = NULL;
    pCollection->m_cpToBeEnabledProfile = NULL;
    pCollection->m_RegistrationState    = RTCRS_NOT_REGISTERED;

    return hr;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::UnregisterClientFromSIPProxy

    start a new unREGISTER transaction with the SIP proxy
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::UnregisterClientFromSIPProxy(
    __in ProxyServices_t::ProfileCollection_t*   pCollection
    )
{
    ASSERT(pCollection);

    //make sure we have a profile to disable
    if (pCollection->m_cpEnabledProfile == NULL)
    {
        return E_FAIL;
    }

    if (pCollection->m_Unregistering)
    {
        //we are already unregistering!
        return S_OK;
    }

    CComPtr<IRTCClientProvisioning> cpProvisioning;
    CComPtr<IRTCClient>             cpClient;

    HRESULT hr;

    cpClient = GetRTCClientPointer();
    if (! cpClient)
    {
        return E_FAIL;
    }

    hr = GetRTCClientPointer()->QueryInterface(
        IID_IRTCClientProvisioning,
        reinterpret_cast<VOID**>(&cpProvisioning)
        );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"QueryInterface failed to get IRTCClientProvisioning [0x%x]", hr));
        ASSERT(FALSE);

        return hr;
    }

    hr = cpProvisioning->DisableProfile( pCollection->m_cpEnabledProfile );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"QueryInterface failed to get IRTCClientProvisioning [0x%x]", hr));
        return hr;
    }

    //force an update of our state
    hr = pCollection->m_cpEnabledProfile->get_State(&pCollection->m_RegistrationState);
    if (FAILED(hr))
    {
        //set a failure value in the registration state
        pCollection->m_RegistrationState = RTCRS_ERROR;
    }
    
    if (pCollection->m_RegistrationState == RTCRS_UNREGISTERING) 
    {
        //if we are already registered (or in the process of registering) then
        //we need to wait for the unregistered event.
        pCollection->m_Unregistering = true;
    }
    else
    {
        //otherwise we are done unregistering
        pCollection->m_Unregistering    = false;
        pCollection->m_cpEnabledProfile = NULL;
    }
      
    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::OnRegistrationStateChangeEvent

    Handles a RegistrationStateChange event

    Parameters:
        pEvent: [in] the pointer to the IRTCRegistrationStateChangeEvent object

    Returns:
        S_OK indicates success, otherwise failure
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::OnRegistrationStateChangeEvent(
    __in IRTCRegistrationStateChangeEvent* pEvent
    )
{
    ASSERT(pEvent != NULL);

    CComPtr<IRTCProfile>    cpProfile;

    //Get the profile from the event
    HRESULT hr = pEvent->get_Profile(&cpProfile);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get a profile from the registration event - error code = 0x%x", hr));
        return hr;
    }

    RTC_REGISTRATION_STATE RegistrationState = RTCRS_ERROR;

    //Get the new registration state
    hr = pEvent->get_State(&RegistrationState);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get the registration state from the event object - error code = 0x%x", hr));
        return hr;
    }

    //Proxy the events to the appropriate collections
    OnRegistrationStateChangeEvent(
        cpProfile,
        RegistrationState,
        &m_SIPProxyCollection
        );

    OnRegistrationStateChangeEvent(
        cpProfile,
        RegistrationState,
        &m_BackupProxyCollection
        );

    //Update status based on our registration state change
    UpdateRegistrationStatus(pEvent);

    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::OnRegistrationStateChangeEvent

    Handle the registration state change event for one specific server
    (and profile collection)
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::OnRegistrationStateChangeEvent(
    __in IRTCProfile*                            pProfile,
    RTC_REGISTRATION_STATE                       RegistrationState,
    __in ProxyServices_t::ProfileCollection_t*   pCollection
    )
{
    ASSERT(pProfile && pCollection);

    //Check to see if this event effects one of the profiles in our collection
    if (! PhoneAppUtilities_t::AreCOMPointersEqual<IRTCProfile>(pProfile, pCollection->m_cpEnabledProfile) &&
        ! PhoneAppUtilities_t::AreCOMPointersEqual<IRTCProfile>(pProfile, pCollection->m_cpToBeEnabledProfile)
       )
    {
        return E_FAIL;
    }

    //Update registration state for the enabled profile
    if (PhoneAppUtilities_t::AreCOMPointersEqual<IRTCProfile>(pProfile, pCollection->m_cpEnabledProfile))
    {
        pCollection->m_RegistrationState = RegistrationState;
    }

    //Event was caused by unregistering the enabled profile (there might be a new profile)
    //otherwise this event affects our enabled profile only (there is no new profile)
    ASSERT((pCollection->m_Unregistering) || pCollection->m_cpToBeEnabledProfile == NULL);

    switch (RegistrationState)
    {
    case RTCRS_UNREGISTERING:
    case RTCRS_LOCAL_PA_LOGGED_OFF:
    case RTCRS_REMOTE_PA_LOGGED_OFF:
        break;

    case RTCRS_REGISTERING:
        break;

    case RTCRS_REGISTERED:
        ASSERT(!pCollection->m_Unregistering);
    case RTCRS_NOT_REGISTERED:
    case RTCRS_REJECTED:
    case RTCRS_ERROR:
    case RTCRS_LOGGED_OFF:
        //we only call DisableProfile on the "Enabled" profile.
        if (pCollection->m_Unregistering)
        {
            //remove the flag stating we are unregistering
            pCollection->m_Unregistering = false;

            //CComPtr - setting to NULL releases the reference
            pCollection->m_cpEnabledProfile = NULL;

            //enabled the "to be enabled" profile if needed
            if (pCollection->m_cpToBeEnabledProfile != NULL)
            {
                RegisterClientWithSIPProxy(pCollection);
            }
        }
        else
        {
            //The overall registration state has changed for this device.
            //We need to update the active profile for this device
            UpdateActiveProfile();
        }
        break;

    default:
        //huh? This isn't possible...
        ASSERT(FALSE);
        return E_UNEXPECTED;
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::UpdateActiveProfile

    Bookkeeping function that determine which profile (main or backup)
    is the currently active profile used for registration/subscriptions/dialing
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::UpdateActiveProfile()
{
    RTC_REGISTRATION_STATE  RegState            = RTCRS_ERROR;
    IRTCProfile*            pNewActiveProfile   = NULL;

    //check if the "main" proxy is active (registered)
    if (m_SIPProxyCollection.m_cpEnabledProfile != NULL)
    {
        m_SIPProxyCollection.m_cpEnabledProfile->get_State(&RegState);

        if (RegState == RTCRS_REGISTERED)
        {
            pNewActiveProfile = m_SIPProxyCollection.m_cpEnabledProfile;
        }
    }

    //if the main proxy is not active, try the backup
    if (! pNewActiveProfile && m_BackupProxyCollection.m_cpEnabledProfile != NULL)
    {
        m_BackupProxyCollection.m_cpEnabledProfile->get_State(&RegState);

        if (RegState == RTCRS_REGISTERED)
        {
            pNewActiveProfile = m_BackupProxyCollection.m_cpEnabledProfile;
        }
    }

    //now we have the new active profile - update the necessary settings
    if (PhoneAppUtilities_t::AreCOMPointersEqual<IRTCProfile>(pNewActiveProfile, m_cpActiveSIPProfile))
    {
        //setting has changed - nothing to do
        return S_OK;
    }

    m_cpActiveSIPProfile = pNewActiveProfile;

    //if both profiles are not enabled, we have nothing to update...
    if (m_cpActiveSIPProfile == NULL)
    {
        return S_OK;
    }

    //if our voicemail settings have been waiting for an active server - subscribe now
    if ((m_VoicemailCollection.m_Flags & SubscriptionCollection_t::SUBSCRIBE_AFTER_REGISTER) ||
        (m_VoicemailCollection.m_cpSubscribeProxy == NULL))
    {
        m_VoicemailCollection.m_Flags &= ~(SubscriptionCollection_t::SUBSCRIBE_AFTER_REGISTER);
        SubscribeWithVoicemailServer();
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::UpdateRegistrationStatus

    Update voip registration status
------------------------------------------------------------------------------*/
void
ProxyServices_t::UpdateRegistrationStatus(
    IRTCRegistrationStateChangeEvent* pEvent
    )
{
    UINT NewStatusFlags;

    if ((m_SIPProxyCollection.m_cpEnabledProfile != NULL) ||
        (m_BackupProxyCollection.m_cpEnabledProfile != NULL))
    {
        if ((m_cpActiveSIPProfile != NULL) &&
            ((m_SIPProxyCollection.m_RegistrationState == RTCRS_REGISTERED) ||
            (m_BackupProxyCollection.m_RegistrationState == RTCRS_REGISTERED)))
        {
            //Must have active profile and registered state
            NewStatusFlags = VOIP_REGISTERED_BITMASK;
        }
        else if ((m_SIPProxyCollection.m_RegistrationState == RTCRS_REGISTERING) ||
            (m_BackupProxyCollection.m_RegistrationState == RTCRS_REGISTERING))
        {
            NewStatusFlags = VOIP_REGISTERING_BITMASK;
        }
        else
        {
            //something goes wrong, get the status code and save the error string to registry
            long StatusCode = 0; 

            if (pEvent != NULL)
            {
                pEvent->get_StatusCode(&StatusCode); 
            }

            RegistrySetString(
                SN_VOIP_REGISTRATIONERROR_ROOT, 
                SN_VOIP_REGISTRATIONERROR_PATH, 
                SN_VOIP_REGISTRATIONERROR_VALUE, 
                CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, UIManager_t::GetStringIdForErrorCode(StatusCode))
                ); 

            if ((m_SIPProxyCollection.m_RegistrationState == RTCRS_REJECTED) ||
                (m_SIPProxyCollection.m_RegistrationState == RTCRS_ERROR) ||
                (m_BackupProxyCollection.m_RegistrationState == RTCRS_REJECTED) ||
                (m_BackupProxyCollection.m_RegistrationState == RTCRS_ERROR))
            {
                NewStatusFlags = VOIP_REGISTRATION_ERROR_BITMASK;
            }
            else 
            {
                NewStatusFlags = VOIP_UNREGISTERED_BITMASK;
            }
        }
    }
    else
    {
        if (GetApp()->GetSettings().IsSettingAvailable(Settings_t::SettingTypeSIPSettings) ||
            GetApp()->GetSettings().IsSettingAvailable(Settings_t::SettingTypeBackupSIPSettings))
        {
            NewStatusFlags = VOIP_UNREGISTERED_BITMASK;
        }
        else
        {
            NewStatusFlags = VOIP_NO_SIP_SETTINGS_BITMASK;
        }      
    }

    //If there is a status change, then notify everyone else
    if (NewStatusFlags != m_RegistrationStatusFlags)
    {
        m_RegistrationStatusFlags = NewStatusFlags; 
        
        RegistrySetDWORD(
            SN_VOIP_SERVERSTATUS_ROOT, 
            SN_VOIP_SERVERSTATUS_PATH, 
            SN_VOIP_SERVERSTATUS_VALUE, 
            m_RegistrationStatusFlags
            ); 

        if (m_RegistrationStatusFlags & VOIP_REGISTERED_BITMASK)
        {
            UpdateUserInfoInRegistry(m_cpActiveSIPProfile); 
        }
    }
}

/*------------------------------------------------------------------------------
    ProxyServices_t::OnVoicemailSettingsChange

    Handle new settings indicating our new voicemail proxy server.

    If we have data in the new setting, use it as the proxy. Otherwise,
    use the "active" profile.
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::OnVoicemailSettingsChange()

⌨️ 快捷键说明

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