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

📄 rtcevent.cpp

📁 Windows CE .Net 下面 VOIP编程的经典实例。对于初学Windows 平台下VOIP编程技术的程序员颇具借鉴意义!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    	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 + -