📄 proxyservices.cpp
字号:
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 + -