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