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

📄 proxyservices.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{

    HRESULT hr = S_OK;

    //The voicemail settings have changed - meaning we need to
    //get the new proxy-profile for subscribing with the server.

    //First, determine which RTC profile to use (one set by the CSP, or use the same
    //as the "active" registrar.
    if ( GetApp()->GetSettings().IsSettingAvailable(Settings_t::SettingTypeVoicemailSettings) )
    {
        //clear out any old profile
        m_VoicemailCollection.m_cpSubscribeProxy = NULL;

        //get the new profile
        hr = GetApp()->GetSettings().GetVoicemailProfile(
                            &m_VoicemailCollection.m_cpSubscribeProxy
                            );

        //if this failed - unsubscribe the old value and be done with it
        if (FAILED(hr))
        {
            UnsubscribeFromVoicemailServer();
            return hr;
        }
    }
    else
    {
        //otherwise, we want to use our "active" profile
        m_VoicemailCollection.m_cpSubscribeProxy = NULL;
    }

    return SubscribeWithVoicemailServer();
}

/*------------------------------------------------------------------------------
    ProxyServices_t::SubscribeWithVoicemailServer

    Start the SUBSCRIBE transaction with the proxy server.
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::SubscribeWithVoicemailServer()
{
    HRESULT hr = S_OK;

    //if we are already subscribed to a voice mail server, unsubscribe it first
    if (m_VoicemailCollection.m_cpSubscription != NULL)
    {
        //start unsubscribing
        hr = UnsubscribeFromVoicemailServer();
        if (SUCCEEDED(hr))
        {
            //if this succeeded, then we need to wait for the
            //existing subscription to finish unsubscribing
            m_VoicemailCollection.m_Flags |= SubscriptionCollection_t::SUBSCRIBE_AFTER_UNSUBSCRIBE;
            return S_OK;
        }

        //otherwise, this failed - NULL out the subscription and continue
        m_VoicemailCollection.m_cpSubscription = NULL;
    }

    //if there is no active profile for registration, we always wait for registration done
    //before we start subscription
    if (m_cpActiveSIPProfile == NULL)
    {
        m_VoicemailCollection.m_Flags |= SubscriptionCollection_t::SUBSCRIBE_AFTER_REGISTER;
        return S_OK;
    }

    //we need to choose a profile to subscribe with -
    IRTCProfile* pProxyProfile = m_VoicemailCollection.m_cpSubscribeProxy;

    //special processing if we are sharing the profile with the registration server
    if (pProxyProfile == NULL)
    {
        pProxyProfile = m_cpActiveSIPProfile;
    }

    //now we have the our proxy profile - we can subscribe to the voicemail server
    ce::auto_bstr AcceptedContent = SysAllocString(c_AcceptedContentForSubscription);
    ce::auto_bstr EventPackage    = SysAllocString(c_EventForSubscription);

    if (EventPackage == NULL || AcceptedContent == NULL)
    {
        return E_OUTOFMEMORY;
    }

    //if RTC is not initialized yet, return
    if (GetRTCClientPointer() == NULL)
    {
        return E_FAIL;
    }

    CComPtr<IRTCClientSubscriber>   cpSubscriber;

    hr = GetRTCClientPointer()->QueryInterface(
        IID_IRTCClientSubscriber,
        reinterpret_cast<VOID**>(&cpSubscriber)
        );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get the subscriber object from the RTC client - error 0x%x", hr));
        return hr;
    }

    //start the SUBSCRIBE transaction
    hr = cpSubscriber->CreateSubscription(
                            pProxyProfile,
                            AcceptedContent,
                            EventPackage,
                            NULL,
                            NULL,
                            &m_VoicemailCollection.m_cpSubscription
                            );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to create subscription with subscriber -- error 0x%x", hr));
        return hr;
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::UnsubscribeFromVoicemailServer

    Starts the unSUBSCRIBE transaction with the SIP proxy
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::UnsubscribeFromVoicemailServer()
{
    //make sure we have a valid subscription to unsubscribe with
    if (m_VoicemailCollection.m_cpSubscription == NULL)
    {
        return E_FAIL;
    }

    HRESULT hr = m_VoicemailCollection.m_cpSubscription->Unsubscribe();
    if (FAILED(hr))
    {
        return hr;
    }

    m_VoicemailCollection.m_Flags |= SubscriptionCollection_t::UNSUBSCRIBING;
    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::OnSubscriptionStateChangeEvent

    Handles a Subscription State Change event from the RTC event sink.
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::OnSubscriptionStateChangeEvent(
    IRTCSubscriptionStateChangeEvent* pEvent
    )
{

    ASSERT(pEvent != NULL);

    CComPtr<IRTCSubscription>    cpSubscription;
    //Get the subscription from the event to determine if this is our subscription -
    //otherwise it is a subscription we don't care about
    HRESULT hr = pEvent->get_Subscription(&cpSubscription);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get a subscription from the subscription state change event - error code = 0x%x", hr));
        return hr;
    }

    //validate that this is the subscription we care about.
    if (! PhoneAppUtilities_t::AreCOMPointersEqual<IRTCSubscription>(cpSubscription, m_VoicemailCollection.m_cpSubscription))
    {
        return S_OK;
    }

    RTC_SUBSCRIPTION_STATE SubscriptionState = RTCSUBC_ERROR;

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

    UINT NewVoicemailStatus = VOIP_NO_VOICEMAIL_SETTINGS_BITMASK;

    switch (SubscriptionState)
    {
        case RTCSUBC_SUBSCRIBING:
        case RTCSUBC_UNSUBSCRIBING:
            break;

        case RTCSUBC_SUBSCRIBED:
            ASSERT(!(m_VoicemailCollection.m_Flags & SubscriptionCollection_t::UNSUBSCRIBING));
            NewVoicemailStatus = VOIP_VOICEMAIL_SUBSCRIBED_BITMASK;
            break;

        case RTCSUBC_NOT_SUBSCRIBED:
        case RTCSUBC_LOGGED_OFF:
        case RTCSUBC_ERROR:
            NewVoicemailStatus = (SubscriptionState == RTCSUBC_NOT_SUBSCRIBED) ?
                            VOIP_VOICEMAIL_UNSUBSCRIBED_BITMASK :
                            VOIP_VOICEMAIL_SUBSCRIPTION_ERROR_BITMASK;

            //if we are in the process of unsubscribing...
            if (m_VoicemailCollection.m_Flags & SubscriptionCollection_t::UNSUBSCRIBING)
            {
                m_VoicemailCollection.m_Flags &= ~(SubscriptionCollection_t::UNSUBSCRIBING);
                m_VoicemailCollection.m_cpSubscription = NULL;

                //if we are supposed to start a new SUBSCRIBE transaction, start it now
                if (m_VoicemailCollection.m_Flags & SubscriptionCollection_t::SUBSCRIBE_AFTER_UNSUBSCRIBE)
                {
                    m_VoicemailCollection.m_Flags &= ~(SubscriptionCollection_t::SUBSCRIBE_AFTER_UNSUBSCRIBE);
                    SubscribeWithVoicemailServer();
                }
            }
            break;

        default:
            ASSERT(FALSE);
            return E_UNEXPECTED;
    }

    //If there is a voicemail status change, then notify everyone else
    if (NewVoicemailStatus != m_SubscriptionStatusFlags)
    {
        m_SubscriptionStatusFlags = NewVoicemailStatus; 

        RegistrySetDWORD(
            SN_VOIP_VOICEMAILSTATUS_ROOT, 
            SN_VOIP_VOICEMAILSTATUS_PATH, 
            SN_VOIP_VOICEMAILSTATUS_VALUE, 
            m_SubscriptionStatusFlags
            ); 
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::OnSubscriptionNotificationEvent

    Handles a Subscription Notification event from the RTC event sink
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::OnSubscriptionNotificationEvent(
    __in IRTCSubscriptionNotificationEvent* pEvent
    )
{

    ASSERT(pEvent != NULL);

    CComPtr<IRTCSubscription>    cpSubscription;

    //Get the subscription from the event to determine if this is our subscription -
    //otherwise it is a subscription we don't care about
    HRESULT hr = pEvent->get_Subscription(&cpSubscription);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get a subscription from the subscription state change event - error code = 0x%x", hr));
        return hr;
    }

    //Is this our subscription?
    if (! PhoneAppUtilities_t::AreCOMPointersEqual<IRTCSubscription>(
                                m_VoicemailCollection.m_cpSubscription,
                                cpSubscription
                                ))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"This event concerns a subscription we are not tracking - ignoring..."));
        return S_OK;
    }

    //blindly accept this event (so the server won't continue sending us data...)
    pEvent->Accept(NULL, NULL);

    ce::auto_bstr ContentType;
    ce::auto_bstr MessageData;

    hr = pEvent->GetNotificationData(
                    &ContentType,
                    &MessageData
                    );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at gettting notification data from event object -- error code = 0x%x", hr));
        return hr;
    }

    if (wcsicmp(ContentType, c_AcceptedContentForSubscription) != 0)
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"This event's content type doesn't match with what we subscribed - ignoring..."));
        return S_OK;
    }

    bool ThereIsVoiceMailWaiting     = false;
    UINT NumberOfNewVoiceMails       = 0;
    UINT NumberOfOldVoiceMails       = 0;
    UINT NumberOfUrgentNewVoiceMails = 0;
    UINT NumberOfUrgentOldVoiceMails = 0;

    hr = ParseVoiceMailNotification(
                    MessageData,
                    SysStringLen(MessageData),
                    &ThereIsVoiceMailWaiting,
                    &NumberOfNewVoiceMails,
                    &NumberOfOldVoiceMails,
                    &NumberOfUrgentNewVoiceMails,
                    &NumberOfUrgentOldVoiceMails
                    );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to parse the voice mail notification"));
        return hr;
    }

    ///TODO: notify the UI to update voicemail indication

    return S_OK;
}

/*------------------------------------------------------------------------------
    ProxyServices_t::OnVoicemailNumberChange

    Cache the voice mail number and notify the the cprog with the updated voice mail number
------------------------------------------------------------------------------*/
HRESULT
ProxyServices_t::OnVoicemailNumberChange()
{
    //handle the voicemail number changes
    return GetApp()->GetSettings().UpdateVoicemailNumber();
}


/*------------------------------------------------------------------------------
    ProxyServices_t::GetBackupSIPProfile
    
    Get the active backup profile object. 

    This will return the enabled backup profile IFF the backup profile is registered
    AND the backup profile is not the active profile (meaning the main profile is active)
------------------------------------------------------------------------------*/
IRTCProfile*    
ProxyServices_t::GetBackupSIPProfile(
    void
    )
{
    if (m_BackupProxyCollection.m_RegistrationState != RTCRS_REGISTERED)
    {
        return NULL;
    }

    if (PhoneAppUtilities_t::AreCOMPointersEqual<IRTCProfile>(m_cpActiveSIPProfile, m_BackupProxyCollection.m_cpEnabledProfile))
    {
        return NULL;
    }
    
    return m_BackupProxyCollection.m_cpEnabledProfile;
}


/*------------------------------------------------------------------------------
    ProxyServices_t::UpdateUserInfoInRegistry
    
    Update provision related user info in registry
    
    Parameters:
        pProfile: if this parameter is NULL, we will clean up the user info in registry
                  otherwise, get user info from this pProfile                  
------------------------------------------------------------------------------*/
void 
ProxyServices_t::UpdateUserInfoInRegistry(
    IRTCProfile* pProfile
    )
{
    if (pProfile == NULL)
    {
        //clear out all the old registry info
        RegistrySetString(
            SN_VOIP_LOCALURI_ROOT, 
            SN_VOIP_LOCALURI_PATH, 
            SN_VOIP_LOCALURI_VALUE, 
            L""
            ); 

        RegistrySetString(
            SN_VOIP_RTCUSERNAME_ROOT, 
            SN_VOIP_RTCUSERNAME_PATH, 
            SN_VOIP_RTCUSERNAME_VALUE, 
            L""
            ); 

        return; 
                
    }

    ce::auto_bstr bstrBuffer;             
    if (SUCCEEDED(m_cpActiveSIPProfile->get_UserURI(&bstrBuffer))) 
    {
        WCHAR*          pLocalURI = bstrBuffer; 
        ce::auto_bstr   bstrFriendlyNumber; 
        HRESULT         hr = GetApp()->GetDialEngine().GetPhoneNumberToDisplay(
                                        bstrBuffer, 
                                        -1,
                                        NULL, 
                                        &bstrFriendlyNumber
                                        ); 
        if (SUCCEEDED(hr))
        {
            pLocalURI = bstrFriendlyNumber; 
        }
        else
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at getting display-able number, hr = 0x%x", hr));             
        }
        
        //save it to registry, do not care about the return value
        RegistrySetString(
            SN_VOIP_LOCALURI_ROOT, 
            SN_VOIP_LOCALURI_PATH, 
            SN_VOIP_LOCALURI_VALUE, 
            pLocalURI
            ); 
    }

    if (SUCCEEDED(m_cpActiveSIPProfile->get_UserName(&bstrBuffer)))
    {
        //save it to registry, do not care about the return value
        RegistrySetString(
            SN_VOIP_RTCUSERNAME_ROOT, 
            SN_VOIP_RTCUSERNAME_PATH, 
            SN_VOIP_RTCUSERNAME_VALUE, 
            bstrBuffer
            ); 
    }

    return; 
    
}

⌨️ 快捷键说明

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