📄 session.cpp
字号:
if (m_Valid == FALSE || m_pSess == NULL) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Accept() called on invalid session!\r\n ") );
return FALSE;
}
if (m_enRSS != RTCSS_INCOMING) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Accept() called on non-incoming session!\r\n ") );
return FALSE;
}
DEBUGMSG( ZONE_STATUS, (L"VoipDemo: Answering incoming session\r\n ") );
m_Valid = TRUE;
hr = m_pSess->Answer();
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Accept() Answer failed 0x%lx\r\n ", hr) );
// It is possible that we've already disconnected thus the session pointer is not valid any more
if ( m_pSess )
{
m_pSess->Terminate( RTCTR_REJECT );
m_pSess->Release();
m_pSess = NULL;
}
m_Valid = FALSE;
return FALSE;
}
else {
return TRUE;
}
} // end CSession::Accept()
/************************************************************************************************
OpenIMSession()
Set CSession variables for IM sesion predating a call to m_NewSession
************************************************************************************************/
HRESULT
CSession::OpenIMSession(
IN P_PARTICIPANT_INFO pPart,
OUT HANDLE& hSession
)
{
HRESULT hr = S_OK;
hSession = NULL;
BOOL bSetURI = FALSE;
// ensure session not already in use
if (m_Valid == TRUE || m_pSess != NULL) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() this session already open, can't open a new one!\r\n ") );
return E_FAIL;
}
// ensure only 1 IM in a session at a time
EnterCriticalSection( g_pcsSessionDataLock );
if (g_bIMSessionOpen) {
LeaveCriticalSection( g_pcsSessionDataLock );
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() an IM session already exists, there is only present support for 1 at a time\r\n ") );
return E_FAIL;
}
g_bIMSessionOpen = TRUE;
// If an IM session exists, ensure that we're opening a call to the same buddy
if (g_bVoiceSessionOpen == TRUE && wcscmp(pPart->get_Addr(), g_bstrCurrentlyConnectedURI) != 0) {
LeaveCriticalSection( g_pcsSessionDataLock );
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() cannot place a call to a different person than we're already talking to.\r\n") );
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: (more info) URI attempted: %s, URI currently connected: %s\r\n", pPart->get_Addr(), g_bstrCurrentlyConnectedURI) );
hr = E_FAIL;
goto Cleanup;
}
// Set the connected URI
if (g_bstrCurrentlyConnectedURI == NULL)
{
if(!NewStrCopy(pPart->get_Addr(), g_bstrCurrentlyConnectedURI)) {
LeaveCriticalSection( g_pcsSessionDataLock );
hr = E_FAIL;
goto Cleanup;
}
bSetURI = TRUE;
}
LeaveCriticalSection( g_pcsSessionDataLock );
// store participant info in session
if (m_sPartInfo.Copy(pPart) == FALSE) {
// memory allocation error
hr = E_FAIL;
goto Cleanup;
}
// set session type IM
m_enRST = RTCST_IM;
// set URI for m_NewSession
NewStrCopy( pPart->get_Addr(), m_bstrRemoteURI );
if (m_bstrRemoteURI == NULL) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() Error allocating memory for a new string!\r\n ") );
hr = E_FAIL;
goto Cleanup;
}
// pass the session handle down to m_NewSession -> Reason blocking call inside
// RTC will invalidate handle passed as return value
hr = m_NewSession(hSession);
Cleanup:
if (FAILED(hr)) {
EnterCriticalSection( g_pcsSessionDataLock );
g_bIMSessionOpen = FALSE;
if (bSetURI) {
SysFreeString(g_bstrCurrentlyConnectedURI);
g_bstrCurrentlyConnectedURI = NULL;
}
LeaveCriticalSection( g_pcsSessionDataLock );
}
return hr;
}
/************************************************************************************************
OpenVoiceSession()
Open a voice session to another party. Depending upon information stored in P_PARTICIPANT_INFO, use a
PC_TO_PC or PC_TO_PHONE connection. For the PC_TO_PHONE, generate a URI including the local SIP gateway and
the phone flag.
Assumption: The user himself is selected in any phone-to-phone calls
************************************************************************************************/
HRESULT
CSession::OpenVoiceSession(
IN P_PARTICIPANT_INFO pPart,
IN RTC_SESSION_TYPE enRST,
OUT HANDLE& hSession
)
{
HRESULT hr = S_OK;
m_enRST = enRST;
hSession = NULL;
BOOL bSetURI = FALSE;
// ensure this is the only voice session (even if there's an incoming, yet unaccepted voice session
EnterCriticalSection( g_pcsSessionDataLock );
if (g_bVoiceSessionOpen == TRUE) {
LeaveCriticalSection( g_pcsSessionDataLock );
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() a voice session already exists, only 1 allowed at any time\r\n ") );
return E_FAIL;
}
g_bVoiceSessionOpen = TRUE;
// If an IM session exists, ensure that we're opening a call to the same buddy
if (g_bIMSessionOpen == TRUE && wcscmp(pPart->get_Addr(), g_bstrCurrentlyConnectedURI) != 0) {
LeaveCriticalSection( g_pcsSessionDataLock );
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() cannot place a call to a different person than we're already talking to.\r\n") );
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: (more info) URI attempted: %s, URI currently connected: %s\r\n", pPart->get_Addr(), g_bstrCurrentlyConnectedURI) );
hr = E_FAIL;
goto Cleanup;
}
// Set the connected URI
if (g_bstrCurrentlyConnectedURI == NULL)
{
if(!NewStrCopy(pPart->get_Addr(), g_bstrCurrentlyConnectedURI)) {
LeaveCriticalSection( g_pcsSessionDataLock );
hr = E_FAIL;
goto Cleanup;
}
bSetURI = TRUE;
}
LeaveCriticalSection( g_pcsSessionDataLock );
// ensure session not already in use
if (m_Valid == TRUE || m_pSess != NULL) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() this session already open, can't open a new one!\r\n ") );
hr = E_FAIL;
goto Cleanup;
}
// store participant info in session
if (m_sPartInfo.Copy(pPart) == FALSE) {
// memory allocation error
hr = E_FAIL;
goto Cleanup;
}
// do some checking for the selected type of action
switch(m_enRST)
{
case RTCST_PHONE_TO_PHONE:
#ifdef NO_PHONE_TO_PHONE
DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Phone to Phone calls presently unsupported, failing\r\n") );
hr = E_FAIL;
goto Cleanup;
#endif
// ensure we have a local phone number to call
if (!m_bstrLocalPhoneURI) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Phone to phone call attempted without local phone number!") );
hr = E_FAIL;
goto Cleanup;
}
// fall thru to check buddy for phone buddy
case RTCST_PC_TO_PHONE:
if (pPart->btBuddyType != BT_PHONE) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Attempting phone call to non-phone buddy!") );
hr = E_FAIL;
goto Cleanup;
}
break;
case RTCST_PC_TO_PC:
if (pPart->btBuddyType != BT_COMPUTER) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Attempting phone call to non-computer buddy!") );
hr = E_FAIL;
goto Cleanup;
}
break;
default: // check for invalid type?
break;
}
// set URI for m_NewSession
NewStrCopy( pPart->get_Addr(), m_bstrRemoteURI );
if (m_bstrRemoteURI == NULL) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() Error allocating memory for a new string!\r\n ") );
hr = E_FAIL;
goto Cleanup;
}
hr = m_NewSession(hSession);
Cleanup:
if (FAILED(hr)) {
EnterCriticalSection( g_pcsSessionDataLock );
g_bVoiceSessionOpen = FALSE;
if (bSetURI) {
SysFreeString(g_bstrCurrentlyConnectedURI);
g_bstrCurrentlyConnectedURI = NULL;
}
LeaveCriticalSection( g_pcsSessionDataLock );
}
return hr;
} // end OpenVoiceSession()
/************************************************************************************************
m_NewSession()
Uses m_bstrRemoteURI as input parameter, assumed to be set by the caller.
Perform all generic tasks for a standard peer-to-peer session. Assume that the caller
has ensured that it's okay to create this session.
Some potential issues:
Creating more than one voice session.
The IRTCSession in this CSession is already active.
Provisioning / Presence info?
m_NewSession will clean up session information after itself.
*************************************************************************************************/
HRESULT
CSession::m_NewSession(HANDLE& hSess)
{
HRESULT hr;
hSess = NULL;
ASSERT (m_Valid == FALSE);
// Create the RTC Session object to add participants to.
hr = g_pRTCClient->CreateSession(m_enRST, m_bstrLocalPhoneURI, m_pProfile, m_lSessionFlags, &m_pSess);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::m_NewSession() CreateSession failed 0x%lx\r\n ", hr) );
return E_FAIL;
}
// store the session with its handle in the container
HANDLE hRetVal = g_pSessionContainer->Add( m_pSess, this );
if (hRetVal != m_pSess) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo:SessionTo - Error adding CSession object to the container!\r\n") );
// fatal error, die
return E_FAIL;
}
DEBUGMSG( ZONE_STATUS | ZONE_CALL, (L"VoipDemo: Calling %s @ %s\r\n ", m_sPartInfo.get_Name(), m_bstrRemoteURI) );
// Signal a call to the specified user.
// This call will block, ensure any variables needed by RTCEvent are all set before this point
hr = m_pSess->AddParticipant(m_bstrRemoteURI, m_sPartInfo.get_Name(), NULL); // does AddRef(m_pSess)
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: AddParticipant(%s) failed 0x%lx\r\n ", m_bstrRemoteURI, hr) );
// Hangup requires a valid session to hangup
// we're calling our own destructor here
g_pSessionContainer->Remove(m_pSess);
return E_FAIL;
}
DEBUGMSG( ZONE_STATUS | ZONE_CALL, (L"VoipDemo: AddParticipant(%s) succeeded\r\n ", m_bstrRemoteURI) );
// validate this session object internally
m_Valid = TRUE;
hSess = m_pSess;
return S_OK;
} // end m_NewSession()
BOOL
CSession::SendIM(
P_IM_MSG msg
)
{
HRESULT hr;
// send an IM message to participant
hr = m_pSess->SendMessage( NULL, msg->szMsg, 0 );
return SUCCEEDED( hr );
} // end SendIM()
/************************************************************************************************
AddParticipantToSession()
Attempt to add a participant to an existing session. This will only work for phone2phone
sessions at present.
NOTE: Need a good way to store the current participants of the session
************************************************************************************************/
BOOL
CSession::AddParticipantToSession(
IN P_PARTICIPANT_INFO pPartInfo,
IN FARPROC fnSWCB
)
{
HRESULT hr;
VARIANT_BOOL vbAddable = VARIANT_FALSE;
ASSERT(pPartInfo);
// the reason for traversing the class to get to the session is so we will get meaningful errors on a debug
hr = m_pSess->get_CanAddParticipants(&vbAddable);
if ( FAILED(hr) || m_enRST != RTCST_PHONE_TO_PHONE || vbAddable == VARIANT_FALSE) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::AddParticipant() : get_CanAddParticipants failed on session 0x%lx\r\n", m_pSess) );
return FALSE;
}
// Add selected participant to current conference call. This will initiate a dialing call to
// the selected user.
// Note: blocking call, ensure everything is set up before this point
DEBUGMSG( ZONE_STATUS | ZONE_CALL, (L"VoipDemo: Adding participant %s to current phone sesion", pPartInfo->get_Addr()) );
hr = m_pSess->AddParticipant(pPartInfo->get_Name(), pPartInfo->get_Addr(), NULL); // does AddRef(m_pSess)
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::AddParticipant() : AddParticipant failed 0x%lx", hr) );
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -