📄 rtcevent.cpp
字号:
hr = g_pRTCClient->PlayRing(
RTCRT_MESSAGE,
VARIANT_TRUE
);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo: Event MessagingEvent() PlayRing failed! 0x%lx\r\n", hr ) );
}
break;
case RTCMSET_STATUS:
RTC_MESSAGING_USER_STATUS enMUS;
hr = pME->get_UserStatus(&enMUS);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event MessagingEvent::get_Status failed! 0x%lx\r\n", hr ) );
}
break;
} // end switch (enMET)
Cleanup:
if (pME)
pME->Release();
if (pSess)
pSess->Release();
if (pPart)
pPart->Release();
return hr;
} // end MessagingEvent()
/************************************************************************************************
HandleBuddyEvent( IN IDispatch* pEvent )
This event is fired when the presence information of a buddy changes.
************************************************************************************************/
HRESULT
HandleBuddyEvent(
IN IDispatch * pEvent
)
{
IRTCBuddyEvent* pRBE = NULL;
HRESULT hr = S_OK;
IRTCBuddy* pBuddy = NULL;
RTC_PRESENCE_STATUS enStatus;
BUDDYTYPE enBt = BT_NONE;
VARIANT_BOOL vbPersistent;
hr = pEvent->QueryInterface(
IID_IRTCBuddyEvent,
(VOID **) &pRBE
);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: Event Failure getting buddy event from QueryInterface 0x%lx\r\n", hr) );
goto Cleanup;
}
// When someone has us as a watcher, but we have no buddy object for them, this event is not fired
hr = pRBE->get_Buddy( &pBuddy ); //does AddRef(pBuddy)
pRBE->Release();
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: Event Failure getting buddy interface on incoming buddy event 0x%lx\r\n", hr) );
goto Cleanup;
}
// If it's a phonebuddy, ignore the status as phone-buddies do not support status
// This is a result of using RTC to store our information on phone buddies...
enBt = DetermineBuddyType(pBuddy, EXISTING_BUDDY);
if ( enBt == BT_NONE || enBt == BT_PHONE) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: BuddyType == BT_PHONE or BT_NONE\r\n") );
goto Cleanup;
}
// get status for debug output
hr = pBuddy->get_Status( &enStatus );
// Pass the status change to the session window and update the GUI
// For now we will not modify the state of any ongoing voice or IM sessions. We will assume that
// these modifications will be handled by the other party's client.
// or (in the case of offline, etc. handled by the session and participant events)
DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"Voipdemo: Event Buddy status change, new status: %s\r\n", GetStringFromVal( enStatus, BuddyStatusTbl)) );
// notify the session window
g_fnSWCB( SWCBM_PRESENCECHANGED, (PVOID) pBuddy, NULL );
// is this a persistent buddy? if it lives only session long, it doesn't effect the listviews
vbPersistent = VARIANT_FALSE;
#ifndef RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
hr = pBuddy->get_Persistent(&vbPersistent);
#else
vbPersistent = VARIANT_TRUE;
#endif
if (vbPersistent) {
DoBuddyStatusChangeListView(pBuddy);
} else {
DEBUGMSG( ZONE_STATUS|ZONE_WARN|ZONE_PRESENCE, (L"Voipdemo: Status change on non-persistent buddy, ignored by the listviews\r\n") );
}
//BSTR bstrNotes = NULL;
// if we allow the user to input a personal away message we can read it here
// hr = pBuddy->get_Notes(&bstrNotes);
Cleanup:
if (pBuddy)
pBuddy->Release();
return hr;
}
/************************************************************************************************
HandleWatcherEvent( IN IDispatch* pEvent )
When the user is not automatically excepting watchers and a watcher requests monitoring status, this event
is fired.
This event is currently only fired when the
************************************************************************************************/
HRESULT
HandleWatcherEvent(
IN IDispatch * pEvent
)
{
HRESULT hr = S_OK;
IRTCWatcherEvent* pRWE = NULL;
IRTCWatcher* pWatcher = NULL;
RTC_WATCHER_STATE enRWS;
BSTR bstrName = NULL;
BSTR bstrURI = NULL;
VARIANT_BOOL vbPersist = VARIANT_FALSE;
DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"Voipdemo: Event incoming watcher request\r\n") );
hr = pEvent->QueryInterface( IID_IRTCWatcherEvent, (void**) &pRWE );
if (FAILED(hr) || !pRWE) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event HandleWatcherEvent QueryInterface failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
hr = pRWE->get_Watcher(&pWatcher); // does AddRef(pWatcher)
if (FAILED(hr) || !pWatcher) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event HandleWatcherEvent get_Watcher failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
hr = pWatcher->get_State(&enRWS);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event HandleWatcherEvent get_State failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
hr = pWatcher->get_Persistent( &vbPersist);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event HandleWatcherEvent get_Persistent failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
hr = pWatcher->get_Name(&bstrName);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event HandleWatcherEvent get_Name failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
hr = pWatcher->get_PresentityURI(&bstrURI);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event HandleWatcherEvent get_PresentityURI failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
// For now automatically add the watcher
DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"Voipdemo: Allowing incoming watcher\r\n") );
enRWS = RTCWS_ALLOWED;
hr = pWatcher->put_State( enRWS );
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo:Event HandleWatcherEvent failed to allow the watcher! 0x%1x\r\n", hr) );
goto Cleanup;
}
#ifdef RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
// if the watcher is persistent
if ( vbPersist ) {
// add him to the database (will do the right thing if he's not there)
AddWatcherRTC(bstrURI, bstrName, (enRWS == RTCWS_BLOCKED) ? L"Blocked" : L"", TRUE );
}
#endif // RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
Cleanup:
SysFreeString(bstrName);
SysFreeString(bstrURI);
if (pWatcher)
pRWE->Release();
if (pWatcher)
pWatcher->Release();
return hr;
}
/************************************************************************************************
HandleRegistrationStateChangeEvent( IN IDispatch* pEvent )
Dbg out Registration events received from RTC Client
************************************************************************************************/
HRESULT
HandleRegistrationStateChangeEvent(
IN IDispatch *pEvent
)
{
IRTCRegistrationStateChangeEvent *pRSCE = NULL;
HRESULT hr = S_OK;
hr = pEvent->QueryInterface(
IID_IRTCRegistrationStateChangeEvent,
(VOID **)&pRSCE
);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event RegistrationState QueryInterface failed! 0x%lx\r\n", hr ) );
return hr;
}
RTC_REGISTRATION_STATE enRRS;
BSTR bstrStatus = NULL;
LONG statuscode = 0;
hr = pRSCE->get_State(&enRRS);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event RegistrationState get_State failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
DEBUGMSG( ZONE_STATUS|ZONE_PROVISION, ( L"VoipDemo:Event RTCE_REGISTRATION_STATE_CHANGE - %s\r\n",\
GetStringFromVal(enRRS, RegistrationStateTbl) ) );
hr = pRSCE->get_StatusText(&bstrStatus);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event RegistrationState get_StatusText failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
hr = pRSCE->get_StatusCode(&statuscode);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo:Event RegistrationState get_StatusCode failed! 0x%lx\r\n", hr ) );
goto Cleanup;
}
pRSCE->Release();
/*
// We're not interested in these messages right now
switch(enRRS) {
case RTCRS_NOT_REGISTERED:
DEBUGMSG( ZONE_ERROR|ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo:Event NOT Registered %S code=%d\n",bstrStatus,statuscode) );
break;
case RTCRS_REGISTERING:
DEBUGMSG( ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo:Event Registering %S code=%d\n",bstrStatus,statuscode) );
break;
case RTCRS_REGISTERED:
DEBUGMSG( ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo:Event Registered %S code=%d\n",bstrStatus,statuscode) );
break;
case RTCRS_REJECTED:
DEBUGMSG( ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo:Event Rejected %S code=%d \n",bstrStatus,statuscode) );
break;
case RTCRS_UNREGISTERING:
DEBUGMSG( ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo:Event Unregistering %S code=%d\n",bstrStatus,statuscode) );
break;
case RTCRS_ERROR:
DEBUGMSG( ZONE_ERROR|ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo:Event Registration Error %S code=%d\n",bstrStatus,statuscode) );
break;
default:
DEBUGMSG( ZONE_ERROR|ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo:Event Registration unexpected state %S code=%d\n",bstrStatus,statuscode) );
break;
}
*/
Cleanup:
SysFreeString(bstrStatus);
if (pRSCE)
pRSCE->Release();
return hr;
}
/************************************************************************************************
SipURIsResolve
Determine if the strings refer to the same computer. If the strings contain an @ symbol, an
email address is assumed and a lowercase wcscmp is performed, otherwise the name is first
resolved as an IP address and if that fails, as a machine name.
************************************************************************************************/
BOOL
SipURIsResolve(BSTR bstrLocalURI, BSTR bstrIncomingURI)
{
HRESULT hr = S_OK;
BOOL bRv = FALSE;
DEBUGMSG( ZONE_STATUS|ZONE_CALL, (L"Voipdemo: Attempting to resolve %s with %s as the same URI\r\n", \
bstrLocalURI, bstrIncomingURI) );
if (wcschr(bstrLocalURI, L'@')) {
// local is an email address, do an email address compare (_wcsicmp)
if (_wcsicmp(bstrLocalURI, bstrIncomingURI) == 0) {
DEBUGMSG( ZONE_STATUS|ZONE_CALL, (L"Voipdemo: Incoming URI matches local URI, they are the same email address\r\n") );
bRv = TRUE;
}
} else if (wcschr(bstrIncomingURI, L'@')) {
DEBUGMSG( ZONE_STATUS|ZONE_CALL, (L"Voipdemo: URI's differ incoming is an email address, local is not\r\n") );
bRv = FALSE;
} else {
if (_wcsicmp(bstrLocalURI, bstrIncomingURI) == 0) {
// we could get lucky...
return TRUE;
}
// local and incoming should be IP addresses or DNS resolvable names
DEBUGMSG( ZONE_STATUS|ZONE_CALL, (L"Voipdemo: URIs are assumed to be IP addresses or DNS resolvable names, attempting to resolve.\r\n") );
WCHAR* pszLocal = NULL;
WCHAR* pszIncoming = NULL;
// strip out the SIP URIs from the names
if (pszLocal = wcschr(bstrLocalURI, L':')) {
pszLocal++; // point after L':'
} else {
pszLocal = bstrLocalURI;
}
if (pszIncoming = wcschr(bstrIncomingURI, L':')) {
pszIncoming++; // point after L':'
} else {
pszIncoming = bstrIncomingURI;
}
// convert the bstrings to char*
CHAR* pstrLocal = NULL;
CHAR* pstrIncoming = NULL;
pstrLocal = new CHAR[sizeof(WCHAR) * wcslen(pszLocal)];
if (!pstrLocal) {
DEBUGMSG( ZONE_ERROR|ZONE_CALL, (L"Voipdemo: Error allocating memory for URI conversion inside address lookup\r\n") );
return FALSE;
}
pstrIncoming = new CHAR[sizeof(WCHAR) * wcslen(pszIncoming)];
if (!pstrIncoming) {
DEBUGMSG( ZONE_ERROR|ZONE_CALL, (L"Voipdemo: Error allocating memory for URI conversion inside address lookup\r\n") );
delete [] pstrLocal;
return FALSE;
}
if ( WideCharToMultiByte( CP_ACP, 0, pszLocal, -1, pstrLocal, sizeof(WCHAR) * wcslen(pszLocal), NULL, NULL)
== 0) {
DEBUGMSG( ZONE_ERROR|ZONE_CALL, (L"VoipDemo: Error converting URI to string for address lookup\r\n") );
hr = E_FAIL;
} else {
if ( WideCharToMultiByte( CP_ACP, 0, pszIncoming, -1, pstrIncoming, sizeof(WCHAR) * wcslen(pszIncoming), NULL, NULL)
== 0) {
DEBUGMSG( ZONE_ERROR|ZONE_CALL, (L"VoipDemo: Error converting URI to string for address lookup\r\n") );
hr = E_FAIL;
}
}
// get the IpAddr ULONGs that the strings refer to
ULONG IpAddrLocal = 0;
ULONG IpAddrIncoming = 0;
if (SUCCEEDED(hr)) {
hr = ResolveHost(pstrLocal, &IpAddrLocal );
}
if (SUCCEEDED(hr)) {
hr = ResolveHost(pstrIncoming, &IpAddrIncoming );
}
delete[] pstrLocal;
delete[] pstrIncoming;
if (FAILED(hr)) {
bRv = FALSE;
} else {
bRv = (IpAddrLocal == IpAddrIncoming);
}
}
return bRv;
}
// Could be host or IP address
HRESULT
ResolveHost(
IN PSTR szHost,
OUT ULONG *pIpAddr
)
{
HRESULT hr;
ASSERT(pIpAddr != NULL);
ULONG IPAddr = inet_addr(szHost);
if (IPAddr != INADDR_NONE)
{
// Host is an IP address
*pIpAddr = IPAddr;
return S_OK;
}
// Try host name resolution.
hr = ResolveHostName(szHost, &IPAddr);
free(szHost);
if (hr != S_OK)
{
return hr;
}
*pIpAddr = IPAddr;
return S_OK;
}
// use gethostbyname to resolve
HRESULT
ResolveHostName(
IN PSTR HostName,
OUT ULONG *pIPAddr
)
{
struct hostent *pHostEntry = gethostbyname(HostName);
if (pHostEntry == NULL)
{
DWORD WinSockErr = WSAGetLastError();
DEBUGMSG( ZONE_ERROR|ZONE_CALL, (L"Voipdemo: gethostbyname failed for host %s, error: 0x%x",
HostName, WinSockErr));
return HRESULT_FROM_WIN32(WinSockErr);
}
// NOTE: Currently we just look at the first one in the address list
*pIPAddr = *((ULONG *)pHostEntry->h_addr_list[0]);
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -