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

📄 rtcs.cpp

📁 Windows CE .Net 下面 VOIP编程的经典实例。对于初学Windows 平台下VOIP编程技术的程序员颇具借鉴意义!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	g_pRTCClient->put_ListenForIncomingSessions(RTCLM_NONE);

	// Close any open sessions and cleanup the session container
	g_pSessionContainer->Clear();
	delete g_pSessionContainer;

	DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"VoipDemo: Setting my status to offline for shutdown.\r\n") );
	g_pRTCPresence->SetLocalPresenceInfo(RTCXS_PRESENCE_OFFLINE,NULL);
	g_pRTCPresence->Release();
	g_pRTCPresence = NULL;


#ifdef USE_AMUNSERVER
	DEBUGMSG( ZONE_STATUS|ZONE_PROVISION, (L"VoipDemo: Disabling the current profile and unregistering with the server.\r\n") );

	if (g_pRTCProvision) {
		g_pRTCProvision->DisableProfile(g_pRTCProfile);

		if (g_pRTCProfile) {
			g_pRTCProfile->Release();
			g_pRTCPresence = NULL;
		}
	}	
#endif

	// Prepare for shutdown will handle all necessary shutdown for presence as well
	DEBUGMSG( ZONE_STATUS|ZONE_INIT, (L"VoipDemo: Signalling RTC to start Asynchronous shutdown.\r\n") );

	// Prepare for shutdown
	// event to signal completed async shutdown
	g_hShutdownEventComplete = CreateEvent( NULL, FALSE, FALSE, NULL );

	g_pRTCClient->PrepareForShutdown();
	
	// Wait for the async shutdown to complete
	WaitForSingleObject( g_hShutdownEventComplete, SHUTDOWN_TIME_LIMIT );
	CloseHandle( g_hShutdownEventComplete );

	HRESULT hr = g_pRTCClient->Shutdown();

	if ( FAILED( hr ) )
		DEBUGMSG( 1, ( L"RTC VoipDemo: Shutdown call on RTCClient object failed!\r\n" ) );


	// final app cleanup
	DEBUGMSG( ZONE_STATUS, (L"VoipDemo: Unregistering event notification interface.\r\n") );
	UnregisterEventInterface();	

	DeleteCriticalSection( g_pcsSessionDataLock );
	delete g_pcsSessionDataLock;
	g_pcsSessionDataLock = NULL;
	
	delete g_pRTCEvents;
	g_pRTCEvents = NULL;

	g_pRTCClient->Release();
	g_pRTCClient = NULL;

	CoUninitialize();
	
	DEBUGMSG( 1, ( L"VoipDemo: Successful termination of RTCClient\r\n" ) );
	
	NKDbgPrintfW( L"VoipDemo: Exiting\r\n" );

	// Signal the message loop that shutdown is done
	PostThreadMessage( g_dwMainThreadID, MSG_END_TESTCASE, 0, 0 );
	return TRUE;
} // end ShutdownRTC()


/************************************************************************************************

  OpenSessionTo
	
	Set up a voice or IM session to the given buddy.
			
 ************************************************************************************************/ 

HANDLE 
OpenSessionTo( 
			  IN P_PARTICIPANT_INFO pPart, 
			  IN RTC_SESSION_TYPE enType, 
			  IN FARPROC fnSWCB
			  )		  
{
	// create a new CSession object
	CSession* pCSession = NULL;
	HANDLE hSess = NULL;
	HRESULT hr = S_OK;

	pCSession = new CSession( (SWCB_FN_PTR) fnSWCB );

	if (pCSession == NULL) {
		DEBUGMSG( ZONE_ERROR, (L"Voipdemo:OpenSessionTo - Error, unable to allocate memory for new session!\r\n") );
		return NULL;
	}

	// Open a session, connect, get the session's handle
	// Note: OpenSession will store the session into the session container
	if (enType != RTCST_IM) {
		// set the local phone in case a PHONE_TO_PHONE connection is desired
		// NOTE: bstrLocalPhoneURI must be of the form: "tel:912345678901" for a successful connection
		if (enType == RTCST_PHONE_TO_PHONE) {
#ifdef NO_PHONE_TO_PHONE
			DEBUGMSG( ZONE_ERROR, (L"Voipdemo:OpenSessionTo - Phone to Phone calls currently not supported!\r\n") );
			delete pCSession;
			return NULL;
#else
			pCSession->put_LocalPhoneURI(g_pLocalUserInfo->get_LocalPhoneURI());
#endif // NO_PHONE_TO_PHONE
		}
		hr = pCSession->OpenVoiceSession( pPart, enType, hSess );
	} else {
		hr = pCSession->OpenIMSession( pPart, hSess );
	}
	if (FAILED(hr)) {
		DEBUGMSG( ZONE_ERROR, (L"Voipdemo:OpenSessionTo - Error creating new voice session!\r\n") );
		delete pCSession;
		return NULL;
	}
	
	return hSess;
} // end OpenSessionTo()


/************************************************************************************************
 
   SessionStop

	Stop the session hSess by calling hangup, then removing it from the session container

 
 ************************************************************************************************/

BOOL 
SessionStop(
			HANDLE hSess
			)
{	
	if (hSess == NULL) {
		DEBUGMSG( ZONE_ERROR, (L"Voipdemo:SessionStop - Attempting to stop a session with NULL handle!\r\n") );
		return FALSE;
	}

	(*g_pSessionContainer)[hSess]->Hangup();
	g_pSessionContainer->Remove(hSess);
	return TRUE;

} 

/************************************************************************************************

  SendIMTo

	Send an instant message on session hSess.
 
 ************************************************************************************************/

BOOL 
SendIMTo( 
		 HANDLE hSess,
		 P_IM_MSG pMsg 
		 )
{
	ASSERT(pMsg);
	if (pMsg->sFrom) 
		DEBUGMSG( ZONE_STATUS|ZONE_CALL, (L"Voipdemo: Sending IM message to %s on session 0x%lx\r\n",\
			pMsg->sFrom->get_Name(), hSess ) );
	else
		DEBUGMSG( ZONE_STATUS|ZONE_CALL, (L"Voipdemo: Sending IM message on session 0x%lx\r\n", hSess ) );

	return (*g_pSessionContainer)[hSess]->SendIM( pMsg );
} // end SendIMTo ()


/************************************************************************************************

  AddParticipantToSession

	Add a participant to a connected session.  
	
	  *Only* possible for Phone-to-Phone type sessions.

 ************************************************************************************************/
BOOL 
AddParticipantToSession( 
						IN P_PARTICIPANT_INFO pPartInfo, 
						HANDLE hSess,
						IN FARPROC fnSWCB
						)
{
	if (!hSess || !g_pSessionContainer->Exist(hSess)) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: AddParticipantToSession() :Attempting to add participant to a non-existent session\r\n") );
		return FALSE;
	}	

	if (pPartInfo->btBuddyType != BT_PHONE) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: AddParticipantToSession() : Attempting to add a non-phone buddy to an \r\n") );
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: AddParticipantToSession() : existing session, only supported for p2p.\r\n") );
		return FALSE;
	}	

	DEBUGMSG( ZONE_STATUS|ZONE_CALL, (L"Voipdemo: Adding another party to call 0x%lx", hSess) );
	return (*g_pSessionContainer)[hSess]->AddParticipantToSession(pPartInfo, fnSWCB);
}

/************************************************************************************************
 
   AddBuddyRTC
 
	Register the buddy with RTC, if persistent is set, the buddy will be saved past the life of the
	program.
 
 ************************************************************************************************/

IRTCBuddy* 
AddBuddyRTC(IN WCHAR* szURI, IN WCHAR* szName, IN BUDDYTYPE eBt, IN VARIANT_BOOL bPersistent, HINSTANCE hInst )
{
	HRESULT hr = S_OK;
	WCHAR szPhoneURI[512];	
	if (eBt == BT_PHONE)
		wsprintf( szPhoneURI, L"%s@%s;user=phone", szURI, DEFAULT_GATEWAYADDRESS );		

	IRTCBuddy* pBuddy = NULL;

	DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"VoipDemo: Adding %s buddy %s with URI %s to RTC buddy list\r\n", \
		(bPersistent == VARIANT_TRUE) ? L"persistent" : L"temporary", szName, szURI) );

	hr = g_pRTCPresence->AddBuddy(
							 (eBt == BT_PHONE) ? szPhoneURI: szURI,		//URI
							 szName,	//Name 
							 (eBt == BT_PHONE) ? szURI : NULL,		//Private Data BLOB (actual phone number for phone)
							 bPersistent, //Save to persistent storage	(if available)	
							 NULL,		// selected profile (NULL to indicate peer-to-peer or use default
#ifdef USE_AMUNSERVER
							 NULL,		// auto-select best profile
#else
							 RTCCS_FORCE_PROFILE, // use peer2peer
#endif
							 &pBuddy
							 );

// note: reference is added for pBuddy after this call, must release upon termination

	if (FAILED(hr) || !pBuddy) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: AddBuddy failed 0x%lx\r\n") );
		return NULL;
	}

#ifdef RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
	if (bPersistent && hInst) {
		// No persistent presence, use the CE DB
		HANDLE hDB = MyAddrDB_Init( hInst );
		CEOID oid = MyAddrDB_Write( hDB, 0, szName, (eBt == BT_PHONE) ? szURI : L"" , (eBt == BT_PHONE) ? szPhoneURI: szURI, (int) ES_ONLINE, (int) eBt );
		MyAddrDB_Close(hDB);
	}
#endif //RTC_PERSISTENT_STORAGE_UNIMPLEMENTED

	return pBuddy;
}

/************************************************************************************************

  RemoveBuddyRTC

	Remove the selected buddy from the RTC buddy list and from storage.

************************************************************************************************/

VOID
RemoveBuddyRTC( IN IRTCBuddy* pBuddy, IN BUDDYTYPE enBt, IN BOOL bPersistent, IN HINSTANCE hInst ) 
{
	HRESULT hr = S_OK;
	BSTR bstrName = NULL;

	if (pBuddy == NULL) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: Error attempting to remove null buddy!") );
		return;
	}
	
#ifdef DEBUG
	pBuddy->get_Name(&bstrName);
#endif DEBUG

	DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"VoipDemo: Removing %s buddy %s with from RTC buddy list\r\n", \
		(bPersistent == VARIANT_TRUE) ? L"persistent" : L"temporary", bstrName) );

#ifdef DEBUG
	SysFreeString(bstrName);
#endif DEBUG

	hr = g_pRTCPresence->RemoveBuddy(pBuddy);

	if (FAILED(hr)) {
		// failed to remove buddy
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: RemoveBuddy() failed 0x%1x\r\n") );
	}
#ifdef RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
	if (bPersistent && hInst) {

		HANDLE hDB = MyAddrDB_Init( hInst );

		// there's no way to get an oid? or is there...
		// find the buddy in the
		pBuddy->get_Name(&bstrName);
		CEOID oid = MyAddrDB_Find( hDB, bstrName, enBt );
		SysFreeString(bstrName);		
		
		if (oid) {
			MyAddrDB_Delete( hDB, oid);
		} else {
			DEBUGMSG( ZONE_ERROR, (L"VoipDemo: Persistent buddy not found in DB from RemoveBuddyRTC()\r\n") );
		}
		
		MyAddrDB_Close(hDB);
	}
#endif //RTC_PERSISTENT_STORAGE_UNIMPLEMENTED

	return;
}

/************************************************************************************************

  EditBuddyRTC

	The buddy was editted in the main window's edit buddy.  Now store the changes internally.

************************************************************************************************/

VOID
EditBuddyRTC(
			 IRTCBuddy* pBuddy, 
			 WCHAR* szName, 
			 WCHAR* szURI,
			 BUDDYTYPE eBt,
			 HINSTANCE hInst
			 )
{
	HRESULT hr;
	if (pBuddy == NULL) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: Error attempting to modify a NULL buddy.\r\n") );
		return;
	}

	BSTR bstrName = NULL;
	hr = pBuddy->get_Name(&bstrName);

#ifdef DEBUG
	BSTR bstrURI = NULL;
	hr = pBuddy->get_PresentityURI(&bstrURI);
#endif DEBUG

#ifdef RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
	CEOID oid = 0;
	HANDLE hDB = NULL;
	// store the buddy changes to the database
	if (hInst) {
		hDB = MyAddrDB_Init( hInst );
		oid = MyAddrDB_Find( hDB, bstrName, BT_NONE );
	}
#endif

	DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"VoipDemo: Modifying buddy %s with URI %s.  New name %s, new URI %s\r\n",\
		bstrName, bstrURI, szName, szURI) );

#ifdef DEBUG
	SysFreeString(bstrURI);
#endif DEBUG

	hr = pBuddy->put_Name(szName);

	WCHAR szPhoneURI[512];

	if (eBt == BT_PHONE) {
		if (eBt == BT_PHONE)
			wsprintf( szPhoneURI, L"%s@%s;user=phone", szURI, DEFAULT_GATEWAYADDRESS );		
	} 
	
	hr = pBuddy->put_PresentityURI((eBt == BT_PHONE) ? szPhoneURI : szURI );
	hr = pBuddy->put_Data((eBt == BT_PHONE) ? szURI : NULL);
#ifdef RTC_PERSISTENT_STORAGE_UNIMPLEMENTED		
	if (hInst) {
		if (oid)
			MyAddrDB_Write( hDB, oid, szName, (eBt == BT_PHONE) ? szURI : L"" , (eBt == BT_PHONE) ? szPhoneURI: szURI, (int) ES_ONLINE, (int) eBt );
		
		MyAddrDB_Close(hDB);
	}
#endif //RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
	
	SysFreeString(bstrName);
	return;
}

/************************************************************************************************

  DetermineBuddyType

	Figure out if a given buddy is a phone buddy or a computer buddy.  We do this both through 
	parsing of the URI string, but also through convention.  

	A buddy created by this program will have a non-null BLOB data for a phone buddy (we store 
	the buddy's non-URI form phone number there.

************************************************************************************************/

BUDDYTYPE
DetermineBuddyType(
				   IRTCBuddy* pBuddy,
				   BOOL bIncoming
				   )
{
	HRESULT hr;
	BUDDYTYPE rv = BT_NONE;
	BSTR bstrBlob = NULL;
	BSTR bstrURI = NULL;

	hr = pBuddy->get_Data(&bstrBlob);
	hr = pBuddy->get_PresentityURI(&bstrURI);

	// bstrBlob will either be NULL or the contacts actual number
	// bstrURI will be any combination of properly formatted sip uri's
	// presently we are not supporting tel URIs

	if (bIncoming) {
		WCHAR* pEndLabel = NULL;
		WCHAR* pBeginAt = NULL;
		WCHAR* pBeginUserEqPhone = NULL;

		// need to parse the URI string to get the phone number
		pBeginUserEqPhone = wcsstr(bstrURI, L";user=phone");
		
		if (!pBeginUserEqPhone) {
			// computer
			rv = BT_COMPUTER;
		} else {
			// phone, pull the phone number out and store to the blob
			pEndLabel = wcsstr(bstrURI, L":"); // end of "SIP:" or "TEL:"
			if (pEndLabel) pEndLabel++; // point after ':'
			pBeginAt = wcsstr(bstrURI, L"@");
			ASSERT(pBeginAt != NULL); // make sure we found it
			
			pBeginAt = NULL; // point end of string to null;
			ASSERT(wcslen(pEndLabel)); // must be non-zero.
						
			hr = pBuddy->put_Data(pEndLabel);
			
			rv = BT_PHONE;
		}
	} else if (wcslen(bstrBlob) == 0) {
		// not incoming, no stored number
		rv = BT_COMPUTER;
	} else {
		// not incoming, bstrBlob has the straight phone# of our buddy
		// NOTE: we could check to see if the gateway is correct.
		rv = BT_PHONE;
	}

	SysFreeString(bstrBlob);
	SysFreeString(bstrURI);

	return rv;
}

/************************************************************************************************

  GetBuddyStatus

	Return the Voipdemo ESTATUS of a buddy when given his specified buddytype and IRTCBuddy 
	pointer.

 ************************************************************************************************/

ESTATUS GetBuddyStatus(IN IRTCBuddy* pBuddy, IN BUDDYTYPE enBt)
{
	HRESULT hr;
	RTC_PRESENCE_STATUS enRXS;
	ESTATUS esStat;
	if (enBt == BT_PHONE) {
		esStat = ES_ONLINE;
	} else {
		hr = pBuddy->get_Status(&enRXS);
		if (FAILED(hr)) {
			esStat = ES_OFFLINE;
		} else {
			esStat = (ESTATUS) GetResFromIndex(enRXS, EstatRTCTbl);
			//if (esStat == ES_NOSTATUS) esStat = ES_OFFLINE;
		}
	}

	return esStat;
}

/*************************************************************************************************

⌨️ 快捷键说明

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