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

📄 voipapp.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    disable the IP calling, if there is on going voip call, wait till them end

    Returns (HRESULT): S_FALSE if the object is not yet initialized
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::DisableCalling()
{
    if (m_cpRTCClient == NULL)
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Not an initialized object - aborting uninitialization"));
        return S_FALSE;
    }

    return Shutdown();

}


/*------------------------------------------------------------------------------
    VoIPApp_t::UnregisterCallbackInterface

    Unregister our event sink from RTC's event connection point

    Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::UnregisterCallbackInterface()
{
    if (m_cpConnectionPt == NULL)
    {
        return E_FAIL;
    }

    HRESULT hr = m_cpConnectionPt->Unadvise(m_ConnectionPtCookie);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to unadvise (unbind) from the connection point! error code - 0x%x", hr));
        return hr;
    }

    //release our internal members
    m_cpConnectionPt     = NULL;
    m_ConnectionPtCookie = 0;

    return S_OK;
}

/*------------------------------------------------------------------------------
    VoIPApp_t::Event

    Event Sink for the RTC Client

    Parameters:
        RTCEvent: event type of the fired event
        piEvent:  pointer to use for QI representing the type of event

    Returns (HRESULT): indicating whether handling the event succeeded or failed
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::Event(
    RTC_EVENT  RTCEvent,
    IDispatch* pDispatch
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

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

    HRESULT hr = E_NOTIMPL;

    //dispatch the event to the proper Handler (see DispatchEvent fn)
    switch (RTCEvent)
    {
    case RTCE_CLIENT:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_CLIENT"));
        DispatchEvent(IRTCClientEvent, OnRTCClientEvent);
        break;

    case RTCE_SESSION_STATE_CHANGE:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SESSION_STATE_CHANGE"));
        DispatchEvent(IRTCSessionStateChangeEvent, OnSessionStateChangeEvent);
        break;

    case RTCE_PARTICIPANT_STATE_CHANGE:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_PARTICIPANT_STATE_CHANGE"));
        DispatchEvent(IRTCParticipantStateChangeEvent, OnParticipantStateChangeEvent);
        break;

    case RTCE_REGISTRATION_STATE_CHANGE:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_REGISTRATION_STATE_CHANGE"));
        DispatchEvent(IRTCRegistrationStateChangeEvent, OnRegistrationStateChangeEvent);
        break;

    case RTCE_SESSION_REFER_STATUS:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SESSION_REFER_STATUS"));
        DispatchEvent(IRTCSessionReferStatusEvent, OnSessionReferStatusChangeEvent);
        break;

    case RTCE_SESSION_REFERRED:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SESSION_REFERRED"));
        DispatchEvent(IRTCSessionReferredEvent, OnSessionReferredEvent);
        break;


    case RTCE_SUBSCRIPTION_STATE_CHANGE_EVENT:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SUBSCRIPTION_STATE_CHANGE_EVENT"));
        DispatchEvent(IRTCSubscriptionStateChangeEvent, OnSubscriptionStateChangeEvent);
        break;

    case RTCE_SUBSCRIPTION_NOTIFY_EVENT:
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SUBSCRIPTION_NOTIFY_EVENT"));
        DispatchEvent(IRTCSubscriptionNotificationEvent, OnSubscriptionNotificationEvent);
        break;

    default:
        hr = E_NOTIMPL;
        break;
    }

    UpdatePhoneAppStatus(); 
    
    return hr;
}


/*------------------------------------------------------------------------------
    VoIPApp_t::OnRTCClientEvent

    Handles an IRTCClientEvent type event - we only care about the async shutdown event
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnRTCClientEvent(
    IRTCClientEvent* pEvent
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

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

    //determine the type of the event
    RTC_CLIENT_EVENT_TYPE EventType = RTCCET_DEVICE_CHANGE;
    HRESULT               hr        = pEvent->get_EventType(&EventType);

    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get the event type from the client event - error code - 0x%x", hr));
        return hr;
    }

    if (EventType != RTCCET_ASYNC_CLEANUP_DONE)
    {
        return S_FALSE;
    }

    //post the shutdown event
    PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received the RTC Async shutdown event - killing message pump by posting a quit msg"));
    PostMessage(m_NotificationWindow, WM_RTC_SHUTDOWN_COMPLETE, 0, 0);
    return S_OK;
}


/*------------------------------------------------------------------------------
    VoIPApp_t::OnSessionStateChangeEvent

    Handles a session state change event from the RTC event sink
    - notifies the phone app of changes
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnSessionStateChangeEvent(
    IRTCSessionStateChangeEvent* pEvent
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

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

    CComPtr<IRTCSession> cpSession;

    //Get the session object from the event
    HRESULT hr = pEvent->get_Session(&cpSession);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC session from the event - error code = 0x%x", hr));
        return hr;
    }

    RTC_SESSION_STATE NewSessionState = RTCSS_IDLE;

    //pre-fetch the new state of the session
    hr = cpSession->get_State(&NewSessionState);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get the new session state from the session - error code = 0x%x", hr));
        return hr;
    }

    CComPtr<Call_t> cpAffectedCall;

    //find the call who owns this session
    FindCallBySession(cpSession, &cpAffectedCall);

    if (cpAffectedCall == NULL)
    {
        //if we aren't currently tracking this call, and this call is not newly incoming
        //then this is some rogue call we don't care about - simply ignore it
        if (NewSessionState != RTCSS_INCOMING)
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Received a session state change event about a call we don't know - aborting..."));
            return E_UNEXPECTED;
        }

        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received a new IncomingCall event"));
    }
    else
    {
        //otherwise, let the call know there was a change in its session state
        cpAffectedCall->OnRTCSessionStateChangeEvent(pEvent);
    }

    switch (NewSessionState)
    {
    case RTCSS_INCOMING:
        if (PHGetSetting(phsCallForwarding))
        {
            if (Settings_t::s_ForwardingNumber && Settings_t::s_ForwardingNumber[0])
            {
                //there is valid forwaring number, start forwarding
                SaveCallForwardedInfoInRegistry(cpSession); 
                //we don't log the call as missed call here, just forward directly
                return ForwardSession(cpSession); 
            }
            else
            {
                //auto-forwarding number is not valid, might due to something bad happens to registry
                //we need to reset the flag to 'not forwarding' to notify user
                PHSetValue(phsCallForwarding, 0); 
            }
        }

        hr = CreateIncomingCall(cpSession, &cpAffectedCall);
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at creating a new group for incoming call, hr = 0x%x", hr));
            return hr;
        }

        if (ShouldRejectIncomingCall(cpAffectedCall))
        {
            cpAffectedCall->MarkAsRejected(); 
            return cpSession->Terminate(RTCTR_DND); 
        }

        break;

    case RTCSS_DISCONNECTED:

        bool PlayingTone; 
        PlayProgressToneForDisconnectedCall(
                cpAffectedCall, 
                &PlayingTone
                ); 
        
        //now remove the call from our list
        m_CallList.remove(cpAffectedCall);

        //remove the reference we added when we put the group in our list
        static_cast<Call_t*>(cpAffectedCall)->Release();
        
        if (!AreThereAnyCurrentCalls())
        {
            if (IsMuted(m_cpRTCClient))
            {
                m_cpRTCClient->put_AudioMuted(
                                RTCAD_MICROPHONE, 
                                VARIANT_FALSE
                                ); 

            }
            
            if (m_AudioMode == e_vamSpeakerPhone && 
                !PlayingTone && 
                m_UIManager.IsEmpty())
            {
                //simulate a speaker toggle
                OnHookModeChange(HotKeys_t::vkSpeaker, FALSE);
            }
        }

        if (cpAffectedCall == m_cpActiveVoicemailCall)
        {
            m_cpActiveVoicemailCall = NULL; 
        }
        
        break;

    default:         
        break; 
        
    }

    return m_UIManager.OnCallEvent(cpAffectedCall); 

}


/*------------------------------------------------------------------------------
    VoIPApp_t::OnParticipantStateChangeEvent

    Handles a participant state change event from the RTC event sink
    - notifies group of changes to its participants
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnParticipantStateChangeEvent(
    IRTCParticipantStateChangeEvent* pEvent
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

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

    CComPtr<IRTCSession>        cpSession;
    CComPtr<IRTCParticipant>    cpParticipant;

    //Get the participant object from the event
    HRESULT hr = pEvent->get_Participant(&cpParticipant);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC participant from the event - error code = 0x%x", hr));
        return hr;
    }

    //then get the session from the participant
    hr = cpParticipant->get_Session(&cpSession);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC session from the participant - error code = 0x%x", hr));
        return hr;
    }


    //find our group by the session and notify it of the change
    CComPtr<Call_t> cpAffectedCall;
    FindCallBySession(cpSession, &cpAffectedCall);

    ///: For now, we don't do anything on a participant state change event, other than notify the group.
    ///: However, this will probably change after we implement multiparty calling...
    if ( cpAffectedCall != NULL )
    {
        cpAffectedCall->OnRTCParticipantStateChangeEvent(pEvent);
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    VoIPApp_t::OnRegistrationStateChangeEvent

    Handles a RegistrationStateChange event indicating a SIP REGISTER request
    is being handled by the remote proxy
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnRegistrationStateChangeEvent(
    IRTCRegistrationStateChangeEvent* pEvent
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

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

    return m_ProxyServices.OnRegistrationStateChangeEvent(pEvent);

}

/*------------------------------------------------------------------------------
    VoIPApp_t::OnSessionReferStatusChangeEvent

    Handles a session refer status change event from the RTC event sink
    - notifies the phone app of changes

    This notification is handled by the initiator in transfer scenario
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnSessionReferStatusChangeEvent(
    IRTCSessionReferStatusEvent* pEvent
    )
{
    TRACE(ZONE_PHONEAPP_EVENT);

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

    CComPtr<IRTCSession2>   cpSession;

    //Get the session object from the event
    HRESULT hr = pEvent->get_Session(&cpSession);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC session from the event - error code = 0x%x", hr));
        return hr;
    }


    CComPtr<Call_t>    cpAffectedCall;

    //find the group who owns this session
    FindCallBySession(cpSession, &cpAffectedCall);
    if ( cpAffectedCall == NULL )
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received a new RTC_SESSION_REFER_STATUS event w/o associating a call"));
        return E_UNEXPECTED;
    }

    //otherwise, let the group know there was a change in its session state
    hr = cpAffectedCall->OnRTCSessionReferStatusChangeEvent(pEvent);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at handling the Refer status change event, hr = 0x%x", hr)); 
    }

    //this event should not trigger the UI update
    return hr; 

}

/*------------------------------------------------------------------------------
    VoIPApp_t::OnSessionReferredEvent

    Handles a session referred event from the RTC event sink
    - notifies the phone app of changes

    This notification is h

⌨️ 快捷键说明

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