|
|
/************************************************************************
* * * INTEL CORPORATION PROPRIETARY INFORMATION * * * * This software is supplied under the terms of a license * * agreement or non-disclosure agreement with Intel Corporation * * and may not be copied or disclosed except in accordance * * with the terms of that agreement. * * * * Copyright (C) 1997 Intel Corp. All Rights Reserved * * * * $Archive: S:\sturgeon\src\gki\vcs\dcall.cpv $ * * * $Revision: 1.12 $ * $Date: 25 Feb 1997 11:46:24 $ * * * $Author: CHULME $ * * * $Log: S:\sturgeon\src\gki\vcs\dcall.cpv $ //
// Rev 1.12 25 Feb 1997 11:46:24 CHULME
// Memset CallInfo structure to zero to avoid unwanted data
//
// Rev 1.11 17 Jan 1997 15:53:50 CHULME
// Put debug variables on conditional compile to avoid release warnings
//
// Rev 1.10 17 Jan 1997 09:01:22 CHULME
// Changed reg.h to gkreg.h to avoid name conflict with inc directory
//
// Rev 1.9 10 Jan 1997 17:42:04 CHULME
// Added CRV and conferenceID to CallReturnInfo structure
//
// Rev 1.8 10 Jan 1997 16:13:36 CHULME
// Removed MFC dependency
//
// Rev 1.7 20 Dec 1996 16:38:58 CHULME
// Removed extraneous debug statements
//
// Rev 1.6 20 Dec 1996 14:08:32 CHULME
// Swapped send and recv addresses in infoRequestResponse
//
// Rev 1.5 19 Dec 1996 19:11:54 CHULME
// Set originator bit in IRR
//
// Rev 1.4 19 Dec 1996 17:59:52 CHULME
// Use dest addr from ACF in IRR if call made with just Alias
//
// Rev 1.3 17 Dec 1996 18:22:24 CHULME
// Switch src and destination fields on ARQ for Callee
//
// Rev 1.2 02 Dec 1996 23:50:52 CHULME
// Added premptive synchronization code
//
// Rev 1.1 22 Nov 1996 15:21:20 CHULME
// Added VCS log to the header
*************************************************************************/
// dcall.cpp : Provides the implementation for the CCall class
//
#include "precomp.h"
#include <process.h>
#include "GKICOM.H"
#include "dspider.h"
#include "dgkilit.h"
#include "DGKIPROT.H"
#include "gksocket.h"
#include "GKREG.H"
#include "dcall.h"
#include "GATEKPR.H"
#include "h225asn.h"
#include "coder.hpp"
#include "dgkiext.h"
#include <objbase.h>
#include "iras.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// CCall construction
CCall::CCall() { // ABSTRACT: The constructor for the CCall class will initialize
// the member variables.
// AUTHOR: Colin Hulme
#ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_CONDES, "CCall::CCall()\n", 0);
memset(&m_CallIdentifier, 0, sizeof(m_CallIdentifier)); memset(&m_callType, 0, sizeof(CallType)); m_pRemoteInfo = 0; memset(&m_RemoteCallSignalAddress, 0, sizeof(TransportAddress)); m_pDestExtraCallInfo = 0; memset(&m_LocalCallSignalAddress, 0, sizeof(TransportAddress)); m_bandWidth = 0; m_callReferenceValue = 0; memset(&m_conferenceID, 0, sizeof(ConferenceIdentifier)); m_activeMC = 0; m_answerCall = 0;
m_usTimeTilStatus = DEFAULT_STATUS_PERIOD; // Reset on ACF
m_uRetryResetCount = GKCALL_RETRY_INTERVAL_SECONDS; m_uRetryCountdown =GKCALL_RETRY_INTERVAL_SECONDS; m_uMaxRetryCount = GKCALL_RETRY_MAX; m_CFbandWidth = 0;
m_CallReturnInfo.hCall = 0; memset(&m_CallReturnInfo.callModel, 0, sizeof(CallModel)); memset(&m_CallReturnInfo.destCallSignalAddress, 0, sizeof(TransportAddress)); m_CallReturnInfo.bandWidth = 0; m_CallReturnInfo.callReferenceValue = 0; memset(&m_CallReturnInfo.conferenceID, 0, sizeof(ConferenceIdentifier));
m_CallReturnInfo.wError = 0;
m_CFirrFrequency = 0;
m_State = GK_ADM_PENDING; SPIDER_TRACE(SP_STATE, "m_State = GK_ADM_PENDING (%X)\n", this);
m_pRasMessage = 0; m_usRetryCount = 0; }
/////////////////////////////////////////////////////////////////////////////
// CCall destruction
CCall::~CCall() { // ABSTRACT: The destructor for the CCall class must free the
// memory allocated for the Alias addresses. It does this by
// deleting the structures and walking the link list.
// AUTHOR: Colin Hulme
SeqAliasAddr *pAA1, *pAA2; #ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_CONDES, "CCall::~CCall()\n", 0);
m_CallReturnInfo.hCall = 0; // Delete self reference
// Delete allocated memory for sequence of alias addresses
pAA1 = m_pRemoteInfo; while (pAA1 != 0) { pAA2 = pAA1->next; if (pAA1->value.choice == h323_ID_chosen) { SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value); delete pAA1->value.u.h323_ID.value; } SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1); delete pAA1; pAA1 = pAA2; }
pAA1 = m_pDestExtraCallInfo; while (pAA1 != 0) { pAA2 = pAA1->next; if (pAA1->value.choice == h323_ID_chosen) { SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value); delete pAA1->value.u.h323_ID.value; } SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1); delete pAA1; pAA1 = pAA2; }
// Delete memory for last RAS message if still allocated
if (m_pRasMessage) { SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage); delete m_pRasMessage; m_pRasMessage = 0; } }
HRESULT CCall::AddRemoteInfo(AliasAddress& rvalue) { // ABSTRACT: This procedure is called to add an alias address
// to the link list of alias addresses. This will
// be called for each alias on receiving a GKI_AdmissionRequest.
// A local copy is made to avoid reliance on the client
// keeping the memory valid.
// This procedure returns 0 if successful and non-zero
// for a failure.
// AUTHOR: Colin Hulme
SeqAliasAddr *p1; unsigned short uIdx; unsigned short *pus; #ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CRegistration::AddRemoteInfo(%X)\n", rvalue.choice);
if (m_pRemoteInfo == 0) // First one in the list
{ m_pRemoteInfo = new SeqAliasAddr; SPIDER_TRACE(SP_NEWDEL, "new m_pRemoteInfo = %X\n", m_pRemoteInfo); if (m_pRemoteInfo == 0) return (GKI_NO_MEMORY); memset(m_pRemoteInfo, 0, sizeof(SeqAliasAddr)); p1 = m_pRemoteInfo; } else { for (p1 = m_pRemoteInfo; p1->next != 0; p1 = p1->next) ; // walk the list til last entry
p1->next = new SeqAliasAddr; SPIDER_TRACE(SP_NEWDEL, "new p1->next = %X\n", p1->next); if (p1->next == 0) return (GKI_NO_MEMORY); memset(p1->next, 0, sizeof(SeqAliasAddr)); p1 = p1->next; } p1->next = 0; // initialize new structure fields
p1->value = rvalue; if (p1->value.choice == h323_ID_chosen) { pus = new unsigned short[p1->value.u.h323_ID.length]; SPIDER_TRACE(SP_NEWDEL, "new pus = %X\n", pus); if (pus == 0) return (GKI_NO_MEMORY); memset(pus, 0, sizeof(unsigned short) * p1->value.u.h323_ID.length); for (uIdx = 0; uIdx < p1->value.u.h323_ID.length; uIdx++) *(pus + uIdx) = *(p1->value.u.h323_ID.value + uIdx); p1->value.u.h323_ID.value = pus; } return (GKI_OK); }
HRESULT CCall::AddDestExtraCallInfo(AliasAddress& rvalue) { // ABSTRACT: This procedure is called to add an alias address
// to the link list of alias addresses. This will
// be called for each alias on receiving a GKI_AdmissionRequest.
// A local copy is made to avoid reliance on the client
// keeping the memory valid.
// This procedure returns 0 if successful and non-zero
// for a failure.
// AUTHOR: Colin Hulme
SeqAliasAddr *p1; unsigned short uIdx; unsigned short *pus; #ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CRegistration::AddDestExtraCallInfo(%X)\n", rvalue.choice);
if (m_pDestExtraCallInfo == 0) // First one in the list
{ m_pDestExtraCallInfo = new SeqAliasAddr; SPIDER_TRACE(SP_NEWDEL, "new m_pDestExtraCallInfo = %X\n", m_pDestExtraCallInfo); if (m_pDestExtraCallInfo == 0) return (GKI_NO_MEMORY); memset(m_pDestExtraCallInfo, 0, sizeof(SeqAliasAddr)); p1 = m_pDestExtraCallInfo; } else { for (p1 = m_pDestExtraCallInfo; p1->next != 0; p1 = p1->next) ; // walk the list til last entry
p1->next = new SeqAliasAddr; SPIDER_TRACE(SP_NEWDEL, "new p1->next = %X\n", p1->next); if (p1->next == 0) return (GKI_NO_MEMORY); memset(p1->next, 0, sizeof(SeqAliasAddr)); p1 = p1->next; } p1->next = 0; // initialize new structure fields
p1->value = rvalue; if (p1->value.choice == h323_ID_chosen) { pus = new unsigned short[p1->value.u.h323_ID.length]; SPIDER_TRACE(SP_NEWDEL, "new pus = %X\n", pus); if (pus == 0) return (GKI_NO_MEMORY); memset(pus, 0, sizeof(unsigned short) * p1->value.u.h323_ID.length); for (uIdx = 0; uIdx < p1->value.u.h323_ID.length; uIdx++) *(pus + uIdx) = *(p1->value.u.h323_ID.value + uIdx); p1->value.u.h323_ID.value = pus; } return (GKI_OK); }
HRESULT CCall::SetLocalCallSignalAddress(unsigned short usCallTransport) { TransportAddress *pTA;
pTA = g_pReg->GetTransportAddress(usCallTransport); if (pTA == NULL) return (GKI_NO_TA_ERROR); m_LocalCallSignalAddress = *pTA; return (GKI_OK); }
void CCall::SetConferenceID(ConferenceIdentifier *pCID) { if ((pCID == NULL) || (pCID->length == 0)) GenerateConferenceID(); else m_conferenceID = *pCID; }
void CCall::GenerateConferenceID(void) { CoCreateGuid((struct _GUID *)m_conferenceID.value); m_conferenceID.length = 16; }
HRESULT CCall::AdmissionRequest(void) { // ABSTRACT: This procedure will create an AdmissionRequest structure
// call the encoder and send the PDU. If it is successful, it
// will return 0, else it will return an error code. Note: The
// memory allocated for the RAS Message is not freed until either
// a response from the gatekeeper or it times out. This allows
// for retransmission without having to rebuild this message.
// AUTHOR: Colin Hulme
ASN1_BUF Asn1Buf; DWORD dwErrorCode; #ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::AdmissionRequest()\n", 0); ASSERT(g_pCoder); if (g_pCoder == NULL) return (GKI_NOT_INITIALIZED); // Copy call reference value and CRV into the return info structure
m_CallReturnInfo.callReferenceValue = m_callReferenceValue; m_CallReturnInfo.conferenceID = m_conferenceID;
// Allocate a RasMessage structure and initialized to 0
m_usRetryCount = 0; m_uRetryCountdown = m_uRetryResetCount;
m_pRasMessage = new RasMessage; SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage); if (m_pRasMessage == 0) return (GKI_NO_MEMORY); memset(m_pRasMessage, 0, sizeof(RasMessage));
// Setup structure fields for AdmissionRequest
m_pRasMessage->choice = admissionRequest_chosen; if (m_pDestExtraCallInfo != 0) m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_destExtraCallInfo_present; m_pRasMessage->u.admissionRequest.requestSeqNum = g_pReg->GetNextSeqNum(); m_pRasMessage->u.admissionRequest.callType = m_callType; m_pRasMessage->u.admissionRequest.endpointIdentifier = g_pReg->GetEndpointIdentifier(); memcpy(&m_pRasMessage->u.admissionRequest.callIdentifier.guid.value, &m_CallIdentifier, sizeof(GUID)); m_pRasMessage->u.admissionRequest.callIdentifier.guid.length = sizeof(GUID); m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_callIdentifier_present; if (m_answerCall) // Src & Dest are swapped in callee
{ if (g_pReg->GetAlias() != NULL) { m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_destinationInfo_present; } if (m_LocalCallSignalAddress.choice != 0) { m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_destCallSignalAddress_present; } m_pRasMessage->u.admissionRequest.destinationInfo = (PAdmissionRequest_destinationInfo)g_pReg->GetAlias(); m_pRasMessage->u.admissionRequest.destCallSignalAddress = m_LocalCallSignalAddress; m_pRasMessage->u.admissionRequest.srcInfo = (PAdmissionRequest_srcInfo)m_pRemoteInfo; if (m_RemoteCallSignalAddress.choice != 0) { m_pRasMessage->u.admissionRequest.bit_mask |= srcCallSignalAddress_present; m_pRasMessage->u.admissionRequest.srcCallSignalAddress = m_RemoteCallSignalAddress; } } else { if (m_pRemoteInfo != 0) { m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_destinationInfo_present; } else if (m_RemoteCallSignalAddress.choice != 0) { m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_destCallSignalAddress_present; m_pRasMessage->u.admissionRequest.destCallSignalAddress = m_RemoteCallSignalAddress; } m_pRasMessage->u.admissionRequest.destinationInfo = (PAdmissionRequest_destinationInfo)m_pRemoteInfo; m_pRasMessage->u.admissionRequest.srcInfo = (PAdmissionRequest_srcInfo)g_pReg->GetAlias(); } m_pRasMessage->u.admissionRequest.destExtraCallInfo = (PAdmissionRequest_destExtraCallInfo)m_pDestExtraCallInfo; m_pRasMessage->u.admissionRequest.bandWidth = m_bandWidth; m_pRasMessage->u.admissionRequest.callReferenceValue = m_callReferenceValue; m_pRasMessage->u.admissionRequest.conferenceID = m_conferenceID; // The following casts are because ASN1_BOOL is a char and BOOL is an int
// since the values of m_activeMC and m_answerCall are always 0 or 1, the
// cast to char causes no loss of data
m_pRasMessage->u.admissionRequest.activeMC = (ASN1_BOOL)m_activeMC; m_pRasMessage->u.admissionRequest.answerCall = (ASN1_BOOL)m_answerCall;
#ifdef _DEBUG
if (dwGKIDLLFlags & SP_DUMPMEM) DumpMem(m_pRasMessage, sizeof(RasMessage)); #endif
// Encode the PDU & send it
dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf); if (dwErrorCode) return (GKI_ENCODER_ERROR);
// Create a backup copy of the encoded PDU if using debug echo support
if (fGKIEcho) { pEchoBuff = new char[Asn1Buf.length]; SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff); if (pEchoBuff == 0) return (GKI_NO_MEMORY); memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length); nEchoLen = Asn1Buf.length; }
SPIDER_TRACE(SP_PDU, "Send ARQ; pCall = %X\n", this); if (fGKIDontSend == FALSE) if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR) return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
// Free the encoder memory
g_pCoder->Free(Asn1Buf);
return (GKI_OK); }
HRESULT CCall::BandwidthRequest(void) { // ABSTRACT: This procedure will create a bandwidthRequest structure
// call the encoder and send the PDU. If it is successful, it
// will return 0, else it will return an error code.
// AUTHOR: Colin Hulme
ASN1_BUF Asn1Buf; DWORD dwErrorCode; #ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::BandwidthRequest()\n", 0); ASSERT(g_pCoder); if (g_pCoder == NULL) return (GKI_NOT_INITIALIZED); // Allocate a RasMessage structure and initialized to 0
m_usRetryCount = 0; m_uRetryCountdown = m_uRetryResetCount; m_pRasMessage = new RasMessage; SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage); if (m_pRasMessage == 0) return (GKI_NO_MEMORY); memset(m_pRasMessage, 0, sizeof(RasMessage));
// Setup structure fields for BandwidthRequest
m_pRasMessage->choice = bandwidthRequest_chosen; m_pRasMessage->u.bandwidthRequest.bit_mask = callType_present; m_pRasMessage->u.bandwidthRequest.requestSeqNum = g_pReg->GetNextSeqNum(); m_pRasMessage->u.bandwidthRequest.endpointIdentifier = g_pReg->GetEndpointIdentifier(); m_pRasMessage->u.bandwidthRequest.conferenceID = m_conferenceID; m_pRasMessage->u.bandwidthRequest.callReferenceValue = m_callReferenceValue; m_pRasMessage->u.bandwidthRequest.callType = m_callType; m_pRasMessage->u.bandwidthRequest.bandWidth = m_bandWidth; memcpy(&m_pRasMessage->u.bandwidthRequest.callIdentifier.guid.value, &m_CallIdentifier, sizeof(GUID)); m_pRasMessage->u.bandwidthRequest.callIdentifier.guid.length = sizeof(GUID); m_pRasMessage->u.bandwidthRequest.bit_mask |= BandwidthRequest_callIdentifier_present;
#ifdef _DEBUG
if (dwGKIDLLFlags & SP_DUMPMEM) DumpMem(m_pRasMessage, sizeof(RasMessage)); #endif
// Encode the PDU & send it
dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf); if (dwErrorCode) return (GKI_ENCODER_ERROR);
// Create a backup copy of the encoded PDU if using debug echo support
if (fGKIEcho) { pEchoBuff = new char[Asn1Buf.length]; SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff); if (pEchoBuff == 0) return (GKI_NO_MEMORY); memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length); nEchoLen = Asn1Buf.length; }
m_State = GK_BW_PENDING; SPIDER_TRACE(SP_STATE, "m_State = GK_BW_PENDING (%X)\n", this);
SPIDER_TRACE(SP_PDU, "Send BRQ; pCall = %X\n", this); if (fGKIDontSend == FALSE) if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR) return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
// Free the encoder memory
g_pCoder->Free(Asn1Buf);
return (GKI_OK); }
HRESULT CCall::DisengageRequest(void) { // ABSTRACT: This procedure will create a disengageRequest structure
// call the encoder and send the PDU. If it is successful, it
// will return 0, else it will return an error code.
// AUTHOR: Colin Hulme
ASN1_BUF Asn1Buf; DWORD dwErrorCode; #ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::DisengageRequest()\n", 0); ASSERT(g_pCoder); if (g_pCoder == NULL) return (GKI_NOT_INITIALIZED); // Allocate a RasMessage structure and initialized to 0
m_usRetryCount = 0; m_uRetryCountdown = m_uRetryResetCount; m_pRasMessage = new RasMessage; SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage); if (m_pRasMessage == 0) return (GKI_NO_MEMORY); memset(m_pRasMessage, 0, sizeof(RasMessage));
// Setup structure fields for DisengageRequest
m_pRasMessage->choice = disengageRequest_chosen; m_pRasMessage->u.disengageRequest.bit_mask = 0; m_pRasMessage->u.disengageRequest.requestSeqNum = g_pReg->GetNextSeqNum(); m_pRasMessage->u.disengageRequest.endpointIdentifier = g_pReg->GetEndpointIdentifier(); m_pRasMessage->u.disengageRequest.conferenceID = m_conferenceID; m_pRasMessage->u.disengageRequest.callReferenceValue = m_callReferenceValue; m_pRasMessage->u.disengageRequest.disengageReason.choice = normalDrop_chosen; memcpy(&m_pRasMessage->u.disengageRequest.callIdentifier.guid.value, &m_CallIdentifier, sizeof(GUID)); m_pRasMessage->u.disengageRequest.callIdentifier.guid.length = sizeof(GUID); m_pRasMessage->u.disengageRequest.bit_mask |= DisengageRequest_callIdentifier_present;
#ifdef _DEBUG
if (dwGKIDLLFlags & SP_DUMPMEM) DumpMem(m_pRasMessage, sizeof(RasMessage)); #endif
// Encode the PDU & send it
dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf); if (dwErrorCode) return (GKI_ENCODER_ERROR);
// Create a backup copy of the encoded PDU if using debug echo support
if (fGKIEcho) { pEchoBuff = new char[Asn1Buf.length]; SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff); if (pEchoBuff == 0) return (GKI_NO_MEMORY); memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length); nEchoLen = Asn1Buf.length; }
m_State = GK_DISENG_PENDING; SPIDER_TRACE(SP_STATE, "m_State = GK_DISENG_PENDING (%X)\n", this);
SPIDER_TRACE(SP_PDU, "Send DRQ; pCall = %X\n", this); if (fGKIDontSend == FALSE) if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR) return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
// Free the encoder memory
g_pCoder->Free(Asn1Buf);
return (GKI_OK); }
HRESULT CCall::AdmissionConfirm(RasMessage *pRasMessage) { // ABSTRACT: This function is called if an admissionConfirm is
// received. We must ensure that this matches an outstanding
// admissionRequest.
// It will delete the memory used for the admissionRequest
// change the state and notify the user by posting a message.
// Additional information contained in the admissionConfirm
// is stored in the CCall class.
// AUTHOR: Colin Hulme
#ifdef _DEBUG
unsigned int nIdx; char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::AdmissionConfirm(%X)\n", pRasMessage); ASSERT(g_pCoder && g_pGatekeeper); if ((g_pCoder == NULL) && (g_pGatekeeper == NULL)) return (GKI_NOT_INITIALIZED); // Verify we are in the correct state, have an outstanding admissionRequest
// and the sequence numbers match
if ((m_State != GK_ADM_PENDING) || (pRasMessage->u.admissionConfirm.requestSeqNum != m_pRasMessage->u.admissionRequest.requestSeqNum))
return (g_pReg->UnknownMessage(pRasMessage));
// Delete allocated RasMessage storage
SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage); delete m_pRasMessage; m_pRasMessage = 0;
// Update member variables
m_State = GK_CALL; SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this);
if (pRasMessage->u.admissionConfirm.bit_mask & irrFrequency_present) { m_CFirrFrequency = pRasMessage->u.admissionConfirm.irrFrequency; m_usTimeTilStatus = (unsigned short)(((DWORD)m_CFirrFrequency * 1000) / GKR_RETRY_TICK_MS); SPIDER_DEBUG(m_usTimeTilStatus); } else m_usTimeTilStatus = 0; // Don't auto-send status datagrams
m_CFbandWidth = pRasMessage->u.admissionConfirm.bandWidth;
m_CallReturnInfo.hCall = this; m_CallReturnInfo.callModel = pRasMessage->u.admissionConfirm.callModel; m_CallReturnInfo.destCallSignalAddress = pRasMessage->u.admissionConfirm.destCallSignalAddress; m_CallReturnInfo.bandWidth = m_CFbandWidth; m_CallReturnInfo.wError = 0;
#ifdef _DEBUG
SPIDER_TRACE(SP_GKI, "PostMessage(hWnd, wBaseMessage + GKI_ADM_CONFIRM, 0, %X)\n", &m_CallReturnInfo); wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue); OutputDebugString(szGKDebug); OutputDebugString("\tconferenceID="); for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++) { wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]); OutputDebugString(szGKDebug); } wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError); OutputDebugString(szGKDebug); #endif
PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_ADM_CONFIRM, 0, (LPARAM)&m_CallReturnInfo);
return (GKI_OK); }
HRESULT CCall::AdmissionReject(RasMessage *pRasMessage) { // ABSTRACT: This function is called if an admissionReject is
// received. We must ensure that this matches an outstanding
// admissionRequest.
// It will delete the memory used for the admissionRequest
// change the state and notify the user by posting a message
// If this function returns GKI_DELETE_CALL, the calling function
// will delete the CCall object.
// AUTHOR: Colin Hulme
#ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::AdmissionReject(%X)\n", pRasMessage);
// Verify we are in the correct state, have an outstanding admissionRequest
// and the sequence numbers match
if ((m_State != GK_ADM_PENDING) || (pRasMessage->u.admissionReject.requestSeqNum != m_pRasMessage->u.admissionRequest.requestSeqNum))
return (g_pReg->UnknownMessage(pRasMessage));
// We deliberately don't free the RasMessage memory. Let the call destructor
// do it - this provides protection from other requests for this hCall.
m_State = GK_DISENGAGED; SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_ADM_REJECT, %X, 0)\n", pRasMessage->u.admissionReject.rejectReason.choice); PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_ADM_REJECT, (WORD)pRasMessage->u.admissionReject.rejectReason.choice, 0L);
return (GKI_DELETE_CALL); }
HRESULT CCall::BandwidthConfirm(RasMessage *pRasMessage) { // ABSTRACT: This function is called if a bandwidthConfirm is
// received. We must ensure that this matches an outstanding
// bandwidthRequest.
// It will delete the memory used for the bandwidthRequest,
// change the state and notify the user by posting a message.
// AUTHOR: Colin Hulme
#ifdef _DEBUG
unsigned int nIdx; char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::BandwidthConfirm(%X)\n", pRasMessage);
// Verify we are in the correct state, have an outstanding admissionRequest
// and the sequence numbers match
if ((m_State != GK_BW_PENDING) || (pRasMessage->u.bandwidthConfirm.requestSeqNum != m_pRasMessage->u.bandwidthRequest.requestSeqNum))
return (g_pReg->UnknownMessage(pRasMessage));
// Delete allocated RasMessage storage
SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage); delete m_pRasMessage; m_pRasMessage = 0;
// Update member variables
m_State = GK_CALL; SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this); m_CFbandWidth = pRasMessage->u.bandwidthConfirm.bandWidth; m_CallReturnInfo.bandWidth = m_CFbandWidth;
// Notify user application
#ifdef _DEBUG
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_BW_CONFIRM, 0, %X)\n", &m_CallReturnInfo); wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue); OutputDebugString(szGKDebug); OutputDebugString("\tconferenceID="); for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++) { wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]); OutputDebugString(szGKDebug); } wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError); OutputDebugString(szGKDebug); #endif
PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_BW_CONFIRM, 0, (LPARAM)&m_CallReturnInfo);
return (GKI_OK); }
HRESULT CCall::BandwidthReject(RasMessage *pRasMessage) { // ABSTRACT: This function is called if a bandwidthReject is
// received. We must ensure that this matches an outstanding
// bandwidthRequest.
// It will delete the memory used for the bandwidthRequest
// change the state and notify the user by posting a message
// AUTHOR: Colin Hulme
#ifdef _DEBUG
unsigned int nIdx; char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::BandwidthReject(%X)\n", pRasMessage);
// Verify we are in the correct state, have an outstanding admissionRequest
// and the sequence numbers match
if ((m_State != GK_BW_PENDING) || (pRasMessage->u.bandwidthReject.requestSeqNum != m_pRasMessage->u.bandwidthRequest.requestSeqNum))
return (g_pReg->UnknownMessage(pRasMessage));
// Delete allocate RasMessage storage
SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage); delete m_pRasMessage; m_pRasMessage = 0;
// Update member variables
m_State = GK_CALL; SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this); m_CFbandWidth = pRasMessage->u.bandwidthReject.allowedBandWidth; m_CallReturnInfo.bandWidth = m_CFbandWidth;
// Notify user application
#ifdef _DEBUG
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_BW_REJECT, %X, &m_CallReturnInfo)\n", pRasMessage->u.bandwidthReject.rejectReason.choice); wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue); OutputDebugString(szGKDebug); OutputDebugString("\tconferenceID="); for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++) { wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]); OutputDebugString(szGKDebug); } wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError); OutputDebugString(szGKDebug); #endif
PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_BW_REJECT, (WORD)pRasMessage->u.bandwidthReject.rejectReason.choice, (LPARAM)&m_CallReturnInfo);
return (GKI_OK); }
HRESULT CCall::SendBandwidthConfirm(RasMessage *pRasMessage) { // ABSTRACT: This function is called when a bandwidthRequest is
// received from the gatekeeper. It will create the
// bandwidthConfirm structure, encode it and send
// it on the net. It posts a message to the user
// notifying them.
// AUTHOR: Colin Hulme
ASN1_BUF Asn1Buf; DWORD dwErrorCode; RasMessage *pRespRasMessage; #ifdef _DEBUG
unsigned int nIdx; char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::SendBandwidthConfirm(%X)\n", pRasMessage);
// Verify we are in the correct state
if (m_State != GK_CALL) return (g_pReg->UnknownMessage(pRasMessage));
// Update member variables
m_CFbandWidth = pRasMessage->u.bandwidthRequest.bandWidth; m_CallReturnInfo.bandWidth = m_CFbandWidth;
// Allocate a RasMessage structure and initialized to 0
pRespRasMessage = new RasMessage; SPIDER_TRACE(SP_NEWDEL, "new pRespRasMessage = %X\n", pRespRasMessage); if (pRespRasMessage == 0) return (GKI_NO_MEMORY); memset(pRespRasMessage, 0, sizeof(RasMessage));
// Setup structure fields for BandwidthConfirm
pRespRasMessage->choice = bandwidthConfirm_chosen; pRespRasMessage->u.bandwidthConfirm.requestSeqNum = pRasMessage->u.bandwidthRequest.requestSeqNum; pRespRasMessage->u.bandwidthConfirm.bandWidth = pRasMessage->u.bandwidthRequest.bandWidth;
#ifdef _DEBUG
if (dwGKIDLLFlags & SP_DUMPMEM) DumpMem(pRespRasMessage, sizeof(RasMessage)); #endif
// Encode the PDU & send it
dwErrorCode = g_pCoder->Encode(pRespRasMessage, &Asn1Buf); if (dwErrorCode) return (GKI_ENCODER_ERROR);
SPIDER_TRACE(SP_PDU, "Send BCF; pCall = %X\n", this); if (fGKIDontSend == FALSE) if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR) return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
// Free the encoder memory
g_pCoder->Free(Asn1Buf);
// Delete allocated RasMessage storage
SPIDER_TRACE(SP_NEWDEL, "del pRespRasMessage = %X\n", pRespRasMessage); delete pRespRasMessage;
// Notify user of received bandwidth request
#ifdef _DEBUG
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_BW_CONFIRM, 0, %X)\n", &m_CallReturnInfo); wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth); OutputDebugString(szGKDebug); wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue); OutputDebugString(szGKDebug); OutputDebugString("\tconferenceID="); for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++) { wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]); OutputDebugString(szGKDebug); } wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError); OutputDebugString(szGKDebug); #endif
PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_BW_CONFIRM, 0, (LPARAM)&m_CallReturnInfo);
return (GKI_OK); }
HRESULT CCall::DisengageConfirm(RasMessage *pRasMessage) { // ABSTRACT: This function is called if a disengageConfirm is
// received. We must ensure that this matches an outstanding
// disengageRequest.
// It will delete the memory used for the disengageRequest,
// change the state and notify the user by posting a message.
// If this function returns GKI_DELETE_CALL, the calling function
// will delete the CCall object.
// AUTHOR: Colin Hulme
#ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::DisengageConfirm(%X)\n", pRasMessage);
// Verify we are in the correct state, have an outstanding disengageRequest
// and the sequence numbers match
if ((m_State != GK_DISENG_PENDING) || (pRasMessage->u.disengageConfirm.requestSeqNum != m_pRasMessage->u.disengageRequest.requestSeqNum))
return (g_pReg->UnknownMessage(pRasMessage));
// We deliberately don't free the RasMessage memory. Let the call destructor
// do it - this provides protection from other requests for this hCall.
// Update member variables
m_State = GK_DISENGAGED; SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
// Notify user application
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_DISENG_CONFIRM, 0, %X)\n", this); PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_DISENG_CONFIRM, 0, (LPARAM)this);
return (GKI_DELETE_CALL); }
HRESULT CCall::DisengageReject(RasMessage *pRasMessage) { // ABSTRACT: This function is called if a disengageReject is
// received. We must ensure that this matches an outstanding
// disengageRequest.
// It will delete the memory used for the disengageRequest
// change the state and notify the user by posting a message
// If this function returns GKI_DELETE_CALL, the calling function
// will delete the CCall object.
// AUTHOR: Colin Hulme
#ifdef _DEBUG
char szGKDebug[80]; #endif
HRESULT hResult = GKI_OK;
SPIDER_TRACE(SP_FUNC, "CCall::DisengageReject(%X)\n", pRasMessage);
// Verify we are in the correct state, have an outstanding disengageRequest
// and the sequence numbers match
if ((m_State != GK_DISENG_PENDING) || (pRasMessage->u.disengageReject.requestSeqNum != m_pRasMessage->u.disengageRequest.requestSeqNum))
return (g_pReg->UnknownMessage(pRasMessage));
// Update member variables
switch (pRasMessage->u.disengageReject.rejectReason.choice) { case requestToDropOther_chosen: // return to GK_CALL state
m_State = GK_CALL; SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this);
// Delete allocate RasMessage storage
SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage); delete m_pRasMessage; m_pRasMessage = 0;
break; case DsnggRjctRsn_ntRgstrd_chosen: default: m_State = GK_DISENGAGED; SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this); hResult = GKI_DELETE_CALL;
// We deliberately don't free the RasMessage memory. Let the call destructor
// do it - this provides protection from other requests for this hCall.
break; }
// Notify user application
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_DISENG_REJECT, %X, hCall)\n", pRasMessage->u.disengageReject.rejectReason.choice); PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_DISENG_REJECT, (WORD)pRasMessage->u.disengageReject.rejectReason.choice, (LPARAM)this);
return (hResult); }
HRESULT CCall::SendDisengageConfirm(RasMessage *pRasMessage) { // ABSTRACT: This function is called when a disengageRequest is
// received from the gatekeeper. It will create the
// disengageConfirm structure, encode it and send
// it on the net. It posts a message to the user
// notifying them.
// AUTHOR: Colin Hulme
ASN1_BUF Asn1Buf; DWORD dwErrorCode; RasMessage *pRespRasMessage; #ifdef _DEBUG
char szGKDebug[80]; #endif
SPIDER_TRACE(SP_FUNC, "CCall::SendDisengageConfirm(%X)\n", pRasMessage); ASSERT(g_pCoder); if (g_pCoder == NULL) return (GKI_NOT_INITIALIZED); // Verify we are in the correct state
if (m_State != GK_CALL) return (g_pReg->UnknownMessage(pRasMessage));
// Allocate a RasMessage structure and initialized to 0
pRespRasMessage = new RasMessage; SPIDER_TRACE(SP_NEWDEL, "new pRespRasMessage = %X\n", pRespRasMessage); if (pRespRasMessage == 0) return (GKI_NO_MEMORY); memset(pRespRasMessage, 0, sizeof(RasMessage));
// Setup structure fields for DisengageConfirm
pRespRasMessage->choice = disengageConfirm_chosen; pRespRasMessage->u.disengageConfirm.requestSeqNum = pRasMessage->u.disengageRequest.requestSeqNum;
#ifdef _DEBUG
if (dwGKIDLLFlags & SP_DUMPMEM) DumpMem(pRespRasMessage, sizeof(RasMessage)); #endif
// Encode the PDU & send it
dwErrorCode = g_pCoder->Encode(pRespRasMessage, &Asn1Buf); if (dwErrorCode) return (GKI_ENCODER_ERROR);
m_State = GK_DISENGAGED; SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
SPIDER_TRACE(SP_PDU, "Send DCF; pCall = %X\n", this); if (fGKIDontSend == FALSE) if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR) return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
// Free the encoder memory
g_pCoder->Free(Asn1Buf);
// Delete allocated RasMessage storage
SPIDER_TRACE(SP_NEWDEL, "del pRespRasMessage = %X\n", pRespRasMessage); delete pRespRasMessage;
// Notify user of received disengage request
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_DISENG_CONFIRM, 0, %X)\n", this); PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_DISENG_CONFIRM, 0, (LPARAM)this);
return (GKI_DELETE_CALL); }
HRESULT CCall::Retry(void) { // ABSTRACT: This function is called by the CRegistration Retry function
// at the configured time interval. It will check if there
// are any outstanding PDUs for the Call object
// If so, they will be retransmitted. If the maximum number of
// retries has expired, the memory will be cleaned up.
// This function will return 0 to the background thread unless
// it wants the thread to terminate. This function will
// also send the IRR status datagram for the conference
// if the time period has expired.
// AUTHOR: Colin Hulme
ASN1_BUF Asn1Buf; DWORD dwErrorCode; #ifdef _DEBUG
char szGKDebug[80]; #endif
HRESULT hResult = GKI_OK;
// SPIDER_TRACE(SP_FUNC, "CCall::Retry()\n", 0);
ASSERT(g_pCoder && g_pGatekeeper); if ((g_pCoder == NULL) && (g_pGatekeeper == NULL)) return (GKI_NOT_INITIALIZED); // Check to see if status datagram is required
if (m_usTimeTilStatus) // No auto-status if 0
{ if (--m_usTimeTilStatus == 0) { // Reset timer
m_usTimeTilStatus = (unsigned short)(((DWORD)m_CFirrFrequency * 1000) / GKR_RETRY_TICK_MS);
hResult = SendInfoRequestResponse(0, 0, TRUE); // send unsolicited status datagram
if (hResult != GKI_OK) return (hResult); } }
// Check to see if PDU retransmission is required
if (m_pRasMessage && (--m_uRetryCountdown == 0)) { // going to retry, reset countdown
m_uRetryCountdown = m_uRetryResetCount;
if (m_usRetryCount <= m_uMaxRetryCount) { // Encode the PDU & resend it
dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf); if (dwErrorCode) return (GKI_ENCODER_ERROR);
SPIDER_TRACE(SP_PDU, "RESend PDU; pCall = %X\n", this); if (fGKIDontSend == FALSE) if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR) return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
// Free the encoder memory
g_pCoder->Free(Asn1Buf); m_usRetryCount++; } else // Retries expired - clean up
{ switch (m_pRasMessage->choice) { case admissionRequest_chosen: m_State = GK_DISENGAGED; SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this); hResult = GKI_DELETE_CALL; break; case bandwidthRequest_chosen: m_State = GK_CALL; SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this); break; case disengageRequest_chosen: m_State = GK_DISENGAGED; SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this); hResult = GKI_DELETE_CALL; break; } SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage); delete m_pRasMessage; m_pRasMessage = 0;
// Notify user that gatekeeper didn't respond
#ifdef RETRY_REREG_FOREVER
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_ERROR, 0, GKI_NO_RESPONSE)\n", 0); PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_ERROR, 0, GKI_NO_RESPONSE); #else
// end the call as if ARJ occurred
SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_ADM_REJECT, ARJ_TIMEOUT, 0)\n", 0); PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_ADM_REJECT, ARJ_TIMEOUT, 0L); #endif
} }
return (hResult); }
HRESULT CCall::SendInfoRequestResponse(CallInfoStruct *pCallInfo, RasMessage *pRasMessage, BOOL fThisCallOnly) { // ABSTRACT: This function is called by the Retry thread if this call
// is due to report an unsolicited status to the gatekeeper.
// It is also called in response to a received IRQ. In the
// case of an IRQ, each active call should chain call the
// next active call. This allows construction of a link
// list of conference information that is then passed to the
// CRegistration::SendInfoRequestResponse function for
// encapsulation into the IRR message.
//
// The fThisCallOnly flag determines whether or not to walk the
// chain of calls in generating the response message.
//
// If fThisCallOnly == TRUE, the chain will not be walked, and
// this routine will call the CRegistration::SendInfoRequestResponse().
// AUTHOR: Colin Hulme, Dan Dexter
CallInfoStruct CallInfo; CallInfoStruct *pCI; #ifdef _DEBUG
char szGKDebug[80]; #endif
HRESULT hResult = GKI_OK;
SPIDER_TRACE(SP_FUNC, "CCall::SendInfoRequestResponse(%X)\n", pCallInfo);
memset(&CallInfo, 0, sizeof(CallInfo)); CallInfo.next = 0; CallInfo.value.bit_mask = 0; CallInfo.value.callReferenceValue = m_callReferenceValue; CallInfo.value.conferenceID = m_conferenceID; memcpy(&CallInfo.value.callIdentifier.guid.value, &m_CallIdentifier, sizeof(GUID)); CallInfo.value.callIdentifier.guid.length = sizeof(GUID); CallInfo.value.bit_mask |= InfoRequestResponse_perCallInfo_Seq_callIdentifier_present;
CallInfo.value.bit_mask |= originator_present; CallInfo.value.callSignaling.bit_mask = recvAddress_present; CallInfo.value.callSignaling.recvAddress = m_LocalCallSignalAddress;
if (m_answerCall) // If I am the callee
{ // look out! if there has not been an ACF, m_CallReturnInfo.destCallSignalAddress
// is uninitialized. m_CallReturnInfo.hCall is set only after ACF
if(m_CallReturnInfo.hCall) { if (m_RemoteCallSignalAddress.choice) { CallInfo.value.callSignaling.sendAddress = m_RemoteCallSignalAddress; CallInfo.value.callSignaling.bit_mask |= sendAddress_present; } CallInfo.value.originator = FALSE; CallInfo.value.callModel = m_CallReturnInfo.callModel; } else { // we are typically in this path because we got an IRQ after
// sending an ARQ.
CallInfo.value.callModel.choice = direct_chosen; } } else // I am the caller
{ // look out! if there has not been an ACF, m_CallReturnInfo.destCallSignalAddress
// is uninitialized. m_CallReturnInfo.hCall is set only after ACF
if(m_CallReturnInfo.hCall) { CallInfo.value.callSignaling.sendAddress = m_CallReturnInfo.destCallSignalAddress; CallInfo.value.callSignaling.bit_mask |= sendAddress_present; CallInfo.value.originator = TRUE; CallInfo.value.callModel = m_CallReturnInfo.callModel; } else { // we are typically in this path because we got an IRQ after
// sending an ARQ.
CallInfo.value.callModel.choice = direct_chosen; } } CallInfo.value.callType = m_callType; CallInfo.value.bandWidth = m_CFbandWidth;
if (pCallInfo) // Add to chain of CallInfo structures
{ for (pCI = pCallInfo; pCI->next != 0; pCI = pCI->next) ; pCI->next = &CallInfo; } else // We're alone - just point to ours
pCallInfo = &CallInfo;
// If the IRR is not just for this call, then get the next call
// and call it's SendInfoRequestResponse() function. If there are no
// more calls, or this IRR was only for this call, call
// g_pReg->SendInfoRequestResponse()
CCall *pNextCall = NULL; if (!fThisCallOnly) { pNextCall = g_pReg->GetNextCall(this); }
if (pNextCall) hResult = pNextCall->SendInfoRequestResponse(pCallInfo, pRasMessage, fThisCallOnly); else hResult = g_pReg->SendInfoRequestResponse(pCallInfo, pRasMessage);
return (hResult); }
//
// MatchSeqNum()
//
// ABSTRACT:
// This function checks to see if the outstanding RAS request(s) it has
// match the sequence number passed in.
//
// RETURNS:
// TRUE if sequence number matches, FALSE otherwise
//
// AUTHOR: Dan Dexter
BOOL CCall::MatchSeqNum(RequestSeqNum seqNum) { BOOL bRet = FALSE; // If there is no RAS message, this sequence
// number can't be ours...
if (!m_pRasMessage) return(FALSE);
// Look at the sequence number in the RAS message and see
// if it matches.
switch(m_pRasMessage->choice) { case gatekeeperRequest_chosen: if (m_pRasMessage->u.gatekeeperRequest.requestSeqNum == seqNum) bRet = TRUE; break; case gatekeeperConfirm_chosen: if (m_pRasMessage->u.gatekeeperConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case gatekeeperReject_chosen: if (m_pRasMessage->u.gatekeeperReject.requestSeqNum == seqNum) bRet = TRUE; break; case registrationRequest_chosen: if (m_pRasMessage->u.registrationRequest.requestSeqNum == seqNum) bRet = TRUE; break; case registrationConfirm_chosen: if (m_pRasMessage->u.registrationConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case registrationReject_chosen: if (m_pRasMessage->u.registrationReject.requestSeqNum == seqNum) bRet = TRUE; break; case unregistrationRequest_chosen: if (m_pRasMessage->u.unregistrationRequest.requestSeqNum == seqNum) bRet = TRUE; break; case unregistrationConfirm_chosen: if (m_pRasMessage->u.unregistrationConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case unregistrationReject_chosen: if (m_pRasMessage->u.unregistrationReject.requestSeqNum == seqNum) bRet = TRUE; break; case admissionRequest_chosen: if (m_pRasMessage->u.admissionRequest.requestSeqNum == seqNum) bRet = TRUE; break; case admissionConfirm_chosen: if (m_pRasMessage->u.admissionConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case admissionReject_chosen: if (m_pRasMessage->u.admissionReject.requestSeqNum == seqNum) bRet = TRUE; break; case bandwidthRequest_chosen: if (m_pRasMessage->u.bandwidthRequest.requestSeqNum == seqNum) bRet = TRUE; break; case bandwidthConfirm_chosen: if (m_pRasMessage->u.bandwidthConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case bandwidthReject_chosen: if (m_pRasMessage->u.bandwidthReject.requestSeqNum == seqNum) bRet = TRUE; break; case disengageRequest_chosen: if (m_pRasMessage->u.disengageRequest.requestSeqNum == seqNum) bRet = TRUE; break; case disengageConfirm_chosen: if (m_pRasMessage->u.disengageConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case disengageReject_chosen: if (m_pRasMessage->u.disengageReject.requestSeqNum == seqNum) bRet = TRUE; break; case locationRequest_chosen: if (m_pRasMessage->u.locationRequest.requestSeqNum == seqNum) bRet = TRUE; break; case locationConfirm_chosen: if (m_pRasMessage->u.locationConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case locationReject_chosen: if (m_pRasMessage->u.locationReject.requestSeqNum == seqNum) bRet = TRUE; break; case infoRequest_chosen: if (m_pRasMessage->u.infoRequest.requestSeqNum == seqNum) bRet = TRUE; break; case infoRequestResponse_chosen: if (m_pRasMessage->u.infoRequestResponse.requestSeqNum == seqNum) bRet = TRUE; break; case nonStandardMessage_chosen: if (m_pRasMessage->u.nonStandardMessage.requestSeqNum == seqNum) bRet = TRUE; break; case unknownMessageResponse_chosen: if (m_pRasMessage->u.unknownMessageResponse.requestSeqNum == seqNum) bRet = TRUE; break; case requestInProgress_chosen: if (m_pRasMessage->u.requestInProgress.requestSeqNum == seqNum) bRet = TRUE; break; case resourcesAvailableIndicate_chosen: if (m_pRasMessage->u.resourcesAvailableIndicate.requestSeqNum == seqNum) bRet = TRUE; break; case resourcesAvailableConfirm_chosen: if (m_pRasMessage->u.resourcesAvailableConfirm.requestSeqNum == seqNum) bRet = TRUE; break; case infoRequestAck_chosen: if (m_pRasMessage->u.infoRequestAck.requestSeqNum == seqNum) bRet = TRUE; break; case infoRequestNak_chosen: if (m_pRasMessage->u.infoRequestNak.requestSeqNum == seqNum) bRet = TRUE; break; default: break; } return bRet; }
//
// MatchCRV()
//
// ABSTRACT:
// This function checks to see if the CallReferenceValue associated
// with this call object matches the CRV passed in.
//
// RETURNS:
// TRUE if CRV number matches, FALSE otherwise
//
// AUTHOR: Dan Dexter
BOOL CCall::MatchCRV(CallReferenceValue crv) { return(crv == m_callReferenceValue); }
|