|
|
/****************************************************************************
* * $Archive: S:\sturgeon\src\callcont\vcs\gkiman.c_v $ * * INTEL Corporation Prorietary Information * * This listing is supplied under the terms of a license agreement * with INTEL Corporation and may not be copied nor disclosed except * in accordance with the terms of that agreement. * * Copyright (c) 1996 Intel Corporation. * * $Revision: 1.77 $ * $Date: 05 Mar 1997 14:30:26 $ * $Author: SBELL1 $ * * Deliverable: * * Abstract: * * Notes: * * Much effort has gone into working around the following constraints of * the GKI interface: * 1) Only one admission request can be pending at a time. This is because * the hCall is unknown until it completes. * 2) Only one bandwidth request per call can be pending at a time. * 3) Any pending bandwidth request must complete before issuing a * disengage request. * 4) Any calls must be disengaged before issuing a deregistration request. * ***************************************************************************/ #ifdef GATEKEEPER
#include "precomp.h"
#include "incommon.h"
#include "ccerror.h"
#include "isrg.h"
#include "gkiexp.h"
#include "callman2.h"
#include "cclock.h"
#include "iras.h"
#include "bestintf.h"
#pragma warning ( default : 4115 4201 4214)
#ifdef FORCE_SERIALIZE_CALL_CONTROL
#define EnterCallControlTop() {CCLOCK_AcquireLock();}
#define LeaveCallControlTop(f) {HRESULT stat; \
stat = f; \ CCLOCK_RelinquishLock(); \ return stat;} #else
#define EnterCallControlTop()
#define LeaveCallControlTop(f) {HRESULT stat; \
stat = f; \ return stat;} #endif
#define GKIMAN_BASE WM_USER
#define MIN_BANDWIDTH 1
#define MAX_BANDWIDTH (0xFFFFFFFF / 100)
#define GKI_ADMITTING_HANDLE ((HANDLE)-1)
#define GKI_BYPASS_HANDLE ((HANDLE)-2)
// GKI Manager state
#define STATE_START 0
#define STATE_CLASS_REGISTERED 1
#define STATE_WINDOW_CREATED 2
#define STATE_REGISTERING 3
#define STATE_REGISTERING_REREG 4
#define STATE_REGISTERING_UNREG 5
#define STATE_REGISTERED 6
#define STATE_ADMITTING 7
#define STATE_ADMITTING_REREG 8
#define STATE_ADMITTING_UNREG 9
#define STATE_DISENGAGING 10
#define STATE_DISENGAGING_REREG 11
#define STATE_UNREGISTERING 12
#define STATE_UNREGISTERING_REREG 13
#define STATE_REG_BYPASS 14
typedef HRESULT (*PGKI_RegistrationRequest)(long lVersion, SeqTransportAddr *pCallSignalAddr, EndpointType *pTerminalType, SeqAliasAddr *pAliasAddr, PCC_VENDORINFO pVendorInfo, HWND hWnd, WORD wBaseMessage, unsigned short usRegistrationTransport /* = ipAddress_chosen */);
typedef HRESULT (*PGKI_UnregistrationRequest)(void);
typedef HRESULT (*PGKI_LocationRequest)(SeqAliasAddr *pLocationInfo);
typedef HRESULT (*PGKI_AdmissionRequest)(unsigned short usCallTypeChoice, SeqAliasAddr *pDestinationInfo, TransportAddress *pDestCallSignalAddress, SeqAliasAddr *pDextExtraCallInfo, LPGUID pCallIdentifier, BandWidth bandWidth, ConferenceIdentifier *pConferenceID, BOOL activeMC, BOOL answerCall, unsigned short usCallTransport /* = ipAddress_chosen */);
typedef HRESULT (*PGKI_BandwidthRequest)(HANDLE hModCall, unsigned short usCallTypeChoice, BandWidth bandWidth);
typedef HRESULT (*PGKI_DisengageRequest)(HANDLE hCall); typedef HRESULT (*PGKI_Initialize)(void); typedef HRESULT (*PGKI_CleanupRequest)(void);
HRESULT Q931CopyAliasNames(PCC_ALIASNAMES *ppTarget, PCC_ALIASNAMES pSource); HRESULT Q931FreeAliasNames(PCC_ALIASNAMES pSource); #define CopyAliasNames Q931CopyAliasNames
#define FreeAliasNames Q931FreeAliasNames
HRESULT CopyVendorInfo( PCC_VENDORINFO *ppDest, PCC_VENDORINFO pSource); HRESULT FreeVendorInfo( PCC_VENDORINFO pVendorInfo);
typedef struct _LISTEN { struct _LISTEN * pNext; PCC_ALIASNAMES pAliasNames; CC_HLISTEN hListen; DWORD dwAddr; WORD wPort; } LISTEN, *PLISTEN;
//
// GKI Manager Global Data
//
CRITICAL_SECTION GkiLock; const char szClassName[] = "GkiManWndClass"; HWND hwndGki = 0; ATOM atomGki = 0; unsigned int uGkiState = STATE_START; PLISTEN pListenList = NULL; unsigned int uGkiCalls = 0; unsigned int uPendingDisengages = 0;
BOOL fGKConfigured = FALSE; BOOL fGKEnabled = FALSE; PCC_ALIASNAMES gpLocalAliasNames = NULL; PCC_VENDORINFO gpVendorInfo = NULL; DWORD g_dwMultipointConfiguration = 0; RASNOTIFYPROC gpRasNotifyProc = NULL;
// HINSTANCE hGkiDll = 0;
PGKI_RegistrationRequest pGKI_RegistrationRequest = NULL; PGKI_UnregistrationRequest pGKI_UnregistrationRequest = NULL; PGKI_LocationRequest pGKI_LocationRequest = NULL; PGKI_AdmissionRequest pGKI_AdmissionRequest = NULL; PGKI_BandwidthRequest pGKI_BandwidthRequest = NULL; PGKI_DisengageRequest pGKI_DisengageRequest = NULL; PGKI_CleanupRequest pGKI_CleanupRequest = NULL; PGKI_Initialize pGKI_Initialize = NULL;
HRESULT ValidateCall(CC_HCALL hCall); HRESULT LastGkiError = CC_GKI_STATE;
//
// Forward declarations
//
LRESULT APIENTRY GkiWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
//
// Helper subroutines
//
#ifdef _DEBUG
typedef struct _GKIMAP { HRESULT hResult; char * pString; } GKIMAP;
GKIMAP GkiErrorNames[] = { GKI_OK, "GKI_OK", GKI_EXIT_THREAD, "GKI_EXIT_THREAD", GKI_REDISCOVER, "GKI_REDISCOVER", GKI_DELETE_CALL, "GKI_DELETE_CALL", GKI_GCF_RCV, "GKI_GCF_RCV", GKI_NO_MEMORY, "GKI_NO_MEMORY", GKI_NO_THREAD, "GKI_NO_THREAD", GKI_HANDLE_ERROR, "GKI_HANDLE_ERROR", GKI_ALREADY_REG, "GKI_ALREADY_REG", GKI_VERSION_ERROR, "GKI_VERSION_ERROR", GKI_ENCODER_ERROR, "GKI_ENCODER_ERROR", GKI_NOT_REG, "GKI_NOT_REG", GKI_BUSY, "GKI_BUSY", GKI_NO_TA_ERROR, "GKI_NO_TA_ERROR", GKI_NO_RESPONSE, "GKI_NO_RESPONSE", GKI_DECODER_ERROR, "GKI_DECODER_ERROR", };
char *StateNames[] = { "STATE_START", "STATE_CLASS_REGISTERED", "STATE_WINDOW_CREATED", "STATE_REGISTERING", "STATE_REGISTERING_REREG", "STATE_REGISTERING_UNREG", "STATE_REGISTERED", "STATE_ADMITTING", "STATE_ADMITTING_REREG", "STATE_ADMITTING_UNREG", "STATE_DISENGAGING", "STATE_DISENGAGING_REREG", "STATE_UNREGISTERING", "STATE_UNREGISTERING_REREG", "STATE_REG_BYPASS", };
char *CallStateNames[] = { "GCS_START", "GCS_WAITING", "GCS_ADMITTING", "GCS_ADMITTING_CLOSE_PENDING", "GCS_ADMITTED", "GCS_CHANGING", "GCS_CHANGING_CLOSE_PENDING", "GCS_DISENGAGING", };
char szBuffer[128];
char * GkiErrorName(char *szFormat, HRESULT hResult) { register int nIndex = sizeof(GkiErrorNames) / sizeof(GkiErrorNames[0]); char szTemp[32];
while (nIndex > 0) { if (GkiErrorNames[--nIndex].hResult == hResult) { wsprintf(szBuffer, szFormat, GkiErrorNames[nIndex].pString); return szBuffer; } }
wsprintf(szTemp, "Unknown(0x%x)", hResult); wsprintf(szBuffer, szFormat, szTemp); return szBuffer; } // GkiErrorName()
char * StateName(char *szFormat, unsigned uState) { char szTemp[32]; if (uState < (sizeof(StateNames)/sizeof(StateNames[0]))) { wsprintf(szBuffer, szFormat, StateNames[uState]); } else { wsprintf(szTemp, "Unknown(%d)", uState); wsprintf(szBuffer, szFormat, szTemp); } return szBuffer; } // StateName()
char * CallStateName(char *szFormat, unsigned uCallState) { char szTemp[32]; if (uCallState <= (sizeof(CallStateNames)/sizeof(CallStateNames[0]))) { wsprintf(szBuffer, szFormat, CallStateNames[uCallState]); } else { wsprintf(szTemp, "Unknown(%d)", uCallState); wsprintf(szBuffer, szFormat, szTemp); } return szBuffer; } // CallStateName()
#else
#define GkiErrorName(x,y) ""
#define StateName(x,y) ""
#define CallStateName(x,y) ""
#endif // _DEBUG
HRESULT MapRegistrationRejectReason(UINT uReason) { #if(0) // this must have been coded by the department of redundancy department
register HRESULT lReason; // TBD - Map reason code into CC_xxx HRESULT
switch (uReason) { case discoveryRequired_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case RgstrtnRjctRsn_invldRvsn_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case invalidCallSignalAddress_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case invalidRASAddress_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case duplicateAlias_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case invalidTerminalType_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case RgstrtnRjctRsn_undfndRsn_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case transportNotSupported_chosen: lReason = CC_GATEKEEPER_REFUSED; break; default: lReason = CC_GATEKEEPER_REFUSED; } // switch
return lReason; #else
return (MAKE_CUSTOM_HRESULT(SEVERITY_ERROR, TRUE, FACILITY_GKIREGISTRATION, (LOWORD(uReason)))); #endif
} // MapRegistrationRejectReason()
HRESULT MapUnregistrationRequestReason(UINT uReason) { HRESULT lReason; lReason = MAKE_CUSTOM_HRESULT(SEVERITY_ERROR,1,FACILITY_GKIUNREGREQ, ERROR_LOCAL_BASE_ID + (LOWORD(uReason))); return lReason; } HRESULT MapAdmissionRejectReason(register UINT uReason) { register HRESULT lReason; #if(0)
// TBD - Map reason code into CC_xxx HRESULT
switch (uReason) { case AdmissionRejectReason_calledPartyNotRegistered_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case ARRn_invldPrmssn_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case AdmssnRjctRsn_rqstDnd_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case AdmssnRjctRsn_undfndRsn_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case AdmissionRejectReason_callerNotRegistered_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case AdmissionRejectReason_routeCallToGatekeeper_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case invldEndpntIdntfr_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case AdmssnRjctRsn_rsrcUnvlbl_chosen: lReason = CC_GATEKEEPER_REFUSED; break; default: lReason = CC_GATEKEEPER_REFUSED; } // switch
#else// last 8 bits are the reason code
lReason = MAKE_CUSTOM_HRESULT(SEVERITY_ERROR,1,FACILITY_GKIADMISSION, ERROR_LOCAL_BASE_ID + (uReason & 0xff)); #endif
return lReason; } // MapAdmissionRejectReason()
HRESULT MapBandwidthRejectReason(register UINT uReason) { register HRESULT lReason;
// TBD - Map reason code into CC_xxx HRESULT
switch (uReason) { case notBound_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case invalidConferenceID_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case BndRjctRsn_invldPrmssn_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case insufficientResources_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case BndRjctRsn_invldRvsn_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case BndRjctRsn_undfndRsn_chosen: lReason = CC_GATEKEEPER_REFUSED; break; default: lReason = CC_GATEKEEPER_REFUSED; } // switch
return lReason; } // MapBandwidthRejectReason()
/*
* NOTES * GkiLock must be locked before calling this routine! */
static PLISTEN ListenEnqueue(register PLISTEN pListen) { pListen->pNext = pListenList; return pListenList = pListen; } // ListenEnqueue()
/*
* NOTES * GkiLock must be locked before calling this routine! */
static PLISTEN ListenDequeue(CC_HLISTEN hListen) { register PLISTEN pListen = pListenList; register PLISTEN pListenPrev;
if (pListen) { if (pListen->hListen == hListen) { pListenList = pListen->pNext; } else { do { pListenPrev = pListen; pListen = pListen->pNext; } while (pListen && pListen->hListen != hListen); if (pListen) { pListenPrev->pNext = pListen->pNext; } } }
return pListen; } // ListenDequeue()
/*
* NOTES * Since the pGkiCall is locked, we don't need a critical section * around the queue manipulation code. */
static PBWREQ BwReqEnqueue(register PGKICALL pGkiCall, register PBWREQ pBwReq) { pBwReq->pNext = NULL; if (pGkiCall->pBwReqHead) { pGkiCall->pBwReqTail->pNext = pBwReq; } else { pGkiCall->pBwReqHead = pBwReq; } return pGkiCall->pBwReqTail = pBwReq; } // BwReqEnqueue()
/*
* NOTES * Since the pGkiCall is locked, we don't need a critical section * around the queue manipulation code. */
static PBWREQ BwReqDequeue(register PGKICALL pGkiCall) { register PBWREQ pBwReq = pGkiCall->pBwReqHead; if (pBwReq) { pGkiCall->pBwReqHead = pBwReq->pNext; } return pBwReq; } // BwReqDequeue()
DWORD GetIpAddress(void) { DWORD dwAddr; char szHostName[128]; if (gethostname(szHostName, sizeof(szHostName)) == 0) { struct hostent *pHostent; pHostent = gethostbyname(szHostName); if (pHostent != NULL) { ASSERT(pHostent->h_addrtype == AF_INET); dwAddr = *((DWORD *)pHostent->h_addr_list[0]); return ntohl(dwAddr); } }
return INADDR_ANY; } // GetIpAddress()
// Caveat: *pAlias should be initialized to all 0 before calling!
static HRESULT CopyAliasItem(SeqAliasAddr *pAlias, PCC_ALIASITEM pAliasItem) { unsigned int uDigit; unsigned int uPrefixLength; unsigned int uDataLength;
if (pAliasItem->pData == NULL || pAliasItem->wDataLength == 0) return CC_BAD_PARAM;
if (pAliasItem->pPrefix) { // Strip off terminating NULs if included in prefix length
uPrefixLength = pAliasItem->wPrefixLength; while (uPrefixLength && pAliasItem->pPrefix[uPrefixLength - 1] == 0) --uPrefixLength; } else { uPrefixLength = 0; }
uDataLength = pAliasItem->wDataLength;
switch (pAliasItem->wType) { case CC_ALIAS_H323_ID: pAlias->value.choice = h323_ID_chosen; pAlias->value.u.h323_ID.value = MemAlloc((uPrefixLength + uDataLength) * sizeof(pAliasItem->pData[0])); if (pAlias->value.u.h323_ID.value == NULL) { ISRERROR(ghISRInst, "CopyAliasItem: Could not allocate %d bytes memory", (uPrefixLength + uDataLength) * sizeof(pAliasItem->pData[0])); return CC_NO_MEMORY; } if (uPrefixLength) { memcpy(&pAlias->value.u.h323_ID.value[0], pAliasItem->pPrefix, uPrefixLength * sizeof(pAliasItem->pPrefix[0])); memcpy(&pAlias->value.u.h323_ID.value[uPrefixLength], pAliasItem->pData, uDataLength * sizeof(pAliasItem->pData[0])); } else { memcpy(&pAlias->value.u.h323_ID.value[0], pAliasItem->pData, uDataLength * sizeof(pAliasItem->pData[0])); } pAlias->value.u.h323_ID.length = (unsigned short)(uPrefixLength + uDataLength); break;
case CC_ALIAS_H323_PHONE: pAlias->value.choice = e164_chosen; if (uPrefixLength) { for (uDigit = 0; uDigit < uPrefixLength; ++uDigit) { pAlias->value.u.e164[uDigit] = (char)pAliasItem->pPrefix[uDigit]; } for (uDigit = 0; uDigit < uDataLength; ++uDigit) { pAlias->value.u.e164[uDigit + uPrefixLength] = (char)pAliasItem->pData[uDigit]; } } else { for (uDigit = 0; uDigit < uDataLength; ++uDigit) { pAlias->value.u.e164[uDigit] = (char)pAliasItem->pData[uDigit]; } } break;
default: ISRERROR(ghISRInst, "CopyAliasItem: Bad alias name type %d", pAliasItem->wType); return CC_BAD_PARAM; } // switch
return NOERROR; } // CopyAliasItem()
/*
* NOTES * Must have Call locked before calling! */
static void GkiAllocCall(PGKICALL pGkiCall, HANDLE hGkiCall) { ASSERT(pGkiCall != NULL); ASSERT(hGkiCall != 0); ASSERT(hGkiCall != GKI_ADMITTING_HANDLE); pGkiCall->hGkiCall = hGkiCall; pGkiCall->uGkiCallState = GCS_ADMITTED; ++uGkiCalls; ISRTRACE(ghISRInst, "GkiAllocCall: uGkiCalls = %d", uGkiCalls); } // GkiAllocCall()
/*
* NOTES * Must have Call locked before calling! */
static HRESULT GkiCancelCall(PGKICALL pGkiCall, void *pConference) { CC_HCALL hCall;
ASSERT(pGkiCall != NULL); pConference = pConference; // Disable compiler warning
hCall = pGkiCall->hCall;
ISRTRACE(ghISRInst, CallStateName("GkiCancelCall <- Call State = %s", pGkiCall->uGkiCallState), 0);
switch (pGkiCall->uGkiCallState) { case GCS_START: break;
case GCS_WAITING: ASSERT(pGkiCall->hGkiCall == 0); if (pGkiCall->bAnswerCall) AcceptCallReject(pGkiCall->pCall, pConference, CC_GATEKEEPER_REFUSED); else PlaceCallReject (pGkiCall->pCall, pConference, CC_GATEKEEPER_REFUSED); break;
case GCS_ADMITTING: case GCS_ADMITTING_CLOSE_PENDING: ASSERT(pGkiCall->hGkiCall == GKI_ADMITTING_HANDLE); if (pGkiCall->bAnswerCall) AcceptCallReject(pGkiCall->pCall, pConference, CC_GATEKEEPER_REFUSED); else PlaceCallReject (pGkiCall->pCall, pConference, CC_GATEKEEPER_REFUSED); break;
case GCS_ADMITTED: case GCS_CHANGING: case GCS_CHANGING_CLOSE_PENDING: case GCS_DISENGAGING: ASSERT(pGkiCall->hGkiCall != 0); ASSERT(pGkiCall->hGkiCall != GKI_ADMITTING_HANDLE); Disengage(pGkiCall->pCall); return NOERROR;
default: ISRERROR(ghISRInst, "GkiCancelCall: Invalid call state %d", pGkiCall->uGkiCallState); } // switch
if (ValidateCall(hCall) == NOERROR && pGkiCall->uGkiCallState != GCS_START) { GkiFreeCall(pGkiCall); }
ISRTRACE(ghISRInst, CallStateName("GkiCancelCall -> Call State = %s", pGkiCall->uGkiCallState), 0); return NOERROR; } // GkiCancelCall()
/*
* NOTES * Must have Call locked before calling! */
static HRESULT GkiCancelAdmitting(PGKICALL pGkiCall, void *pConference) { ASSERT(pGkiCall != NULL); pConference = pConference; // Disable compiler warning
ISRTRACE(ghISRInst, CallStateName("GkiCancelAdmitting <- Call State = %s", pGkiCall->uGkiCallState), 0);
switch (pGkiCall->uGkiCallState) { case GCS_ADMITTING: ASSERT(pGkiCall->hGkiCall == GKI_ADMITTING_HANDLE); pGkiCall->hGkiCall = 0; pGkiCall->uGkiCallState = GCS_WAITING; break;
case GCS_ADMITTING_CLOSE_PENDING: ASSERT(pGkiCall->hGkiCall == GKI_ADMITTING_HANDLE); GkiFreeCall(pGkiCall); break;
} // switch
ISRTRACE(ghISRInst, CallStateName("GkiCancelAdmitting -> Call State = %s", pGkiCall->uGkiCallState), 0); return NOERROR; } // GkiCancelAdmitting()
/*
* NOTES * Must have Call locked before calling! */
static HRESULT CheckPendingBandwidth(PGKICALL pGkiCall);
static HRESULT GatekeeperNotFound(PGKICALL pGkiCall, void *pConference) { ASSERT(pGkiCall != NULL); ASSERT(pConference != NULL);
ISRTRACE(ghISRInst, CallStateName("GatekeeperNotFound <- Call State = %s", pGkiCall->uGkiCallState), 0);
switch (pGkiCall->uGkiCallState) { case GCS_START: case GCS_ADMITTED: break;
case GCS_WAITING: case GCS_ADMITTING: GkiOpenCall(pGkiCall, pConference); break;
case GCS_ADMITTING_CLOSE_PENDING: case GCS_CHANGING_CLOSE_PENDING: case GCS_DISENGAGING: GkiCloseCall(pGkiCall); break;
case GCS_CHANGING: pGkiCall->uGkiCallState = GCS_ADMITTED; pGkiCall->uBandwidthAllocated = MAX_BANDWIDTH; CheckPendingBandwidth(pGkiCall); break;
default: ISRERROR(ghISRInst, "GatekeeperNotFound: Invalid call state %d", pGkiCall->uGkiCallState); } // switch
ISRTRACE(ghISRInst, CallStateName("GatekeeperNotFound -> Call State = %s", pGkiCall->uGkiCallState), 0); return NOERROR; } // GatekeeperNotFound()
/*
* NOTES * GkiLock must be locked before calling this routine! */
HRESULT GkiRegister(void) { register HRESULT status = NOERROR;
ASSERT(pListenList != NULL);
switch (uGkiState) { case STATE_START: // Register window class
{ WNDCLASS wndclass = { 0, GkiWndProc, 0, 0, 0, 0, 0, 0, NULL, szClassName }; atomGki = RegisterClass(&wndclass); if (atomGki == 0) { status = HRESULT_FROM_WIN32(GetLastError()); ISRERROR(ghISRInst, "GkiRegister: Error 0x%x registering class", status); break; } } uGkiState = STATE_CLASS_REGISTERED;
// Fall-through to next case
case STATE_CLASS_REGISTERED: // Create window to receive GKI messages
hwndGki = CreateWindow(szClassName, "", WS_OVERLAPPED, 0, 0, 0, 0, 0, 0, 0, NULL); if (hwndGki == 0) { status = HRESULT_FROM_WIN32(GetLastError()); ISRERROR(ghISRInst, "GkiRegister: Error 0x%x creating window", status); break; } uGkiState = STATE_WINDOW_CREATED;
// Fall-through to next case
case STATE_WINDOW_CREATED: { PLISTEN pListen; unsigned uListens = 0; unsigned uAliasNames = 0; SeqTransportAddr *pTransportAddrs; SeqAliasAddr *pAliasAddrs = NULL; SeqAliasAddr *pRegistrationAliasAddrs = NULL; PCC_ALIASITEM pAliasItem; unsigned uIndex; unsigned uDigit; EndpointType TerminalType = {0};
// Count Transport Addresses and Alias Names
pListen = pListenList; while (pListen) { // Count the Transport Address
++uListens;
if (pListen->pAliasNames) { // Count the Alias Names
uAliasNames += pListen->pAliasNames->wCount; } pListen = pListen->pNext; }
// if the separately configured alias names exist, override what was
// in the listen list
if(gpLocalAliasNames) { uAliasNames = gpLocalAliasNames->wCount; }
pTransportAddrs = MemAlloc(uListens * sizeof(*pTransportAddrs)); if (pTransportAddrs == NULL) { ISRERROR(ghISRInst, "GkiRegister: Could not allocate %d Transport Addresses", uListens); return CC_NO_MEMORY; }
if (uAliasNames) { pAliasAddrs = MemAlloc(uAliasNames * sizeof(*pAliasAddrs)); if (pAliasAddrs == NULL) { MemFree(pTransportAddrs); ISRERROR(ghISRInst, "GkiRegister: Could not allocate %d Alias Addresses", uAliasNames); return CC_NO_MEMORY; } }
pListen = pListenList; uListens = 0; uAliasNames = 0; // if the separately configured alias names exist, override what was
// in the listen list
if(gpLocalAliasNames) { pAliasItem = gpLocalAliasNames->pItems; for (uIndex = 0; uIndex < gpLocalAliasNames->wCount; ++uIndex, ++pAliasItem) { pAliasAddrs[uAliasNames].next = &pAliasAddrs[uAliasNames + 1]; switch (pAliasItem->wType) { case CC_ALIAS_H323_ID: pAliasAddrs[uAliasNames].value.choice = h323_ID_chosen; pAliasAddrs[uAliasNames].value.u.h323_ID.length = pAliasItem->wDataLength; pAliasAddrs[uAliasNames].value.u.h323_ID.value = pAliasItem->pData; break;
case CC_ALIAS_H323_PHONE: pAliasAddrs[uAliasNames].value.choice = e164_chosen; memset(pAliasAddrs[uAliasNames].value.u.e164, 0, sizeof(pAliasAddrs[uAliasNames].value.u.e164)); for (uDigit = 0; uDigit < pAliasItem->wDataLength; ++uDigit) { pAliasAddrs[uAliasNames].value.u.e164[uDigit] = (char)pAliasItem->pData[uDigit]; } break;
default: MemFree(pAliasAddrs); ISRERROR(ghISRInst, "GkiRegister: Bad alias name type %d", pAliasItem->wType); return CC_BAD_PARAM; } // switch
++uAliasNames; } // for
} while (pListen) { // Initialize a transport address
// TBD - throw out duplicates
pTransportAddrs[uListens].next = &pTransportAddrs[uListens + 1]; pTransportAddrs[uListens].value.choice = ipAddress_chosen; pTransportAddrs[uListens].value.u.ipAddress.ip.length = 4; *((DWORD *)pTransportAddrs[uListens].value.u.ipAddress.ip.value) = pListen->dwAddr; pTransportAddrs[uListens].value.u.ipAddress.port = pListen->wPort;
// Add any alias names to list (unless separately configured alias names exist)
// TBD - throw out duplicates
if ((gpLocalAliasNames == NULL) && pAliasAddrs && pListen->pAliasNames) { pAliasItem = pListen->pAliasNames->pItems; for (uIndex = 0; uIndex < pListen->pAliasNames->wCount; ++uIndex, ++pAliasItem) { pAliasAddrs[uAliasNames].next = &pAliasAddrs[uAliasNames + 1]; switch (pAliasItem->wType) { case CC_ALIAS_H323_ID: pAliasAddrs[uAliasNames].value.choice = h323_ID_chosen; pAliasAddrs[uAliasNames].value.u.h323_ID.length = pAliasItem->wDataLength; pAliasAddrs[uAliasNames].value.u.h323_ID.value = pAliasItem->pData; break;
case CC_ALIAS_H323_PHONE: pAliasAddrs[uAliasNames].value.choice = e164_chosen; memset(pAliasAddrs[uAliasNames].value.u.e164, 0, sizeof(pAliasAddrs[uAliasNames].value.u.e164)); for (uDigit = 0; uDigit < pAliasItem->wDataLength; ++uDigit) { pAliasAddrs[uAliasNames].value.u.e164[uDigit] = (char)pAliasItem->pData[uDigit]; } break;
default: MemFree(pAliasAddrs); MemFree(pTransportAddrs); ISRERROR(ghISRInst, "GkiRegister: Bad alias name type %d", pAliasItem->wType); return CC_BAD_PARAM; } // switch
++uAliasNames; } // for
} // if
++uListens; pListen = pListen->pNext; } // while
pTransportAddrs[uListens - 1].next = NULL; if (pAliasAddrs) { pAliasAddrs[uAliasNames - 1].next = NULL; }
// Initialize TerminalType
TerminalType.bit_mask = terminal_present; TerminalType.mc = (g_dwMultipointConfiguration)?TRUE:FALSE;
uGkiState = STATE_REGISTERING; ISRTRACE(ghISRInst, "GKI_RegistrationRequest called...", 0); status = pGKI_RegistrationRequest(GKI_VERSION, // lVersion
pTransportAddrs, // pCallSignalAddr
&TerminalType, // pTerminalType
pAliasAddrs, // pRgstrtnRgst_trmnlAls
gpVendorInfo, hwndGki, // hWnd
GKIMAN_BASE, // wBaseMessage
ipAddress_chosen); // usRegistrationTransport
if (status == NOERROR) { ISRTRACE(ghISRInst, GkiErrorName("GKI_RegistrationRequest returned %s", status), 0); } else { ISRERROR(ghISRInst, GkiErrorName("GKI_RegistrationRequest returned %s", status), 0); uGkiState = STATE_WINDOW_CREATED; } if (pAliasAddrs) MemFree(pAliasAddrs); if (pTransportAddrs) MemFree(pTransportAddrs); } break;
case STATE_REGISTERING: case STATE_REGISTERING_REREG: case STATE_REGISTERING_UNREG: uGkiState = STATE_REGISTERING_REREG; break;
case STATE_REGISTERED: uGkiState = STATE_UNREGISTERING_REREG; ISRTRACE(ghISRInst, "GKI_UnregistrationRequest called...", 0); status = pGKI_UnregistrationRequest(); if (status == NOERROR) { ISRTRACE(ghISRInst, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0); } else { ISRERROR(ghISRInst, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0); uGkiState = STATE_REG_BYPASS; ApplyToAllCalls(GatekeeperNotFound); } break;
case STATE_ADMITTING: case STATE_ADMITTING_REREG: case STATE_ADMITTING_UNREG: uGkiState = STATE_ADMITTING_REREG; break;
case STATE_DISENGAGING: uGkiState = STATE_DISENGAGING_REREG; break;
case STATE_DISENGAGING_REREG: break;
case STATE_UNREGISTERING: uGkiState = STATE_UNREGISTERING_REREG; break;
case STATE_UNREGISTERING_REREG: break;
case STATE_REG_BYPASS: break;
default: ISRERROR(ghISRInst, "GkiRegister: Invalid state %d", uGkiState); status = LastGkiError; } // switch
return status; } // GkiRegister()
/*
* NOTES * GkiLock must be locked before calling this routine! */
HRESULT GkiCloseCallNoError(PGKICALL pGkiCall, void *pConference) { ASSERT(GKIExists()); ASSERT(pGkiCall != NULL); pConference = pConference; // Disable compiler warning
if (pGkiCall->uGkiCallState != GCS_START) GkiCloseCall(pGkiCall); return NOERROR; } // GkiCloseCallNoError()
HRESULT GkiUnregister(void) { register HRESULT status = NOERROR; switch (uGkiState) { case STATE_REG_BYPASS: ApplyToAllCalls(GkiCancelCall); uGkiState = STATE_WINDOW_CREATED; break;
case STATE_UNREGISTERING_REREG: uGkiState = STATE_UNREGISTERING; break;
case STATE_UNREGISTERING: break;
case STATE_DISENGAGING_REREG: if (uGkiCalls != 0 || uPendingDisengages != 0) { uGkiState = STATE_DISENGAGING; } else { uGkiState = STATE_REGISTERED; return GkiUnregister(); } break;
case STATE_DISENGAGING: if (uGkiCalls == 0 && uPendingDisengages == 0) { uGkiState = STATE_REGISTERED; return GkiUnregister(); } break;
case STATE_ADMITTING_UNREG: case STATE_ADMITTING_REREG: case STATE_ADMITTING: uGkiState = STATE_ADMITTING_UNREG; break;
case STATE_REGISTERING_UNREG: case STATE_REGISTERING_REREG: case STATE_REGISTERING: uGkiState = STATE_REGISTERING_UNREG; break;
case STATE_REGISTERED: if (uGkiCalls) { // Issue Disengage Request for every call
uGkiState = STATE_DISENGAGING; ApplyToAllCalls(GkiCloseCallNoError); break;
} else { // Issue Unregistration Request
uGkiState = STATE_UNREGISTERING; ISRTRACE(ghISRInst, "GKI_UnregistrationRequest called...", 0); status = pGKI_UnregistrationRequest(); if (status == NOERROR) { ISRTRACE(ghISRInst, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0); } else { ISRERROR(ghISRInst, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0); uGkiState = STATE_WINDOW_CREATED; } } break;
case STATE_WINDOW_CREATED: case STATE_CLASS_REGISTERED: case STATE_START: ISRWARNING(ghISRInst, StateName("GkiUnregister: Already in uninitialized state %s", uGkiState), 0); status = LastGkiError; break;
default: ISRERROR(ghISRInst, "GkiUnregister: Invalid state %d", uGkiState); status = LastGkiError; } // switch
return status; } // GkiUnregister()
void DeInitGkiManager(void) { register PLISTEN pListen;
if(!fGKConfigured) return;
EnterCriticalSection(&GkiLock);
#if 0
// TBD - When called from DllMain PROCESS_DETACH, this does not work because
// apparently the socket to the Gatekeeper has already been closed.
if (uGkiState != STATE_START) { GkiUnregister(); uGkiState = STATE_START; } #else
uGkiState = STATE_START; #endif
while (pListenList) { pListen = pListenList; pListenList = pListenList->pNext; if (pListen->pAliasNames) { FreeAliasNames(pListen->pAliasNames); } MemFree(pListen); }
pGKI_RegistrationRequest = NULL; pGKI_UnregistrationRequest = NULL; pGKI_LocationRequest = NULL; pGKI_AdmissionRequest = NULL; pGKI_BandwidthRequest = NULL; pGKI_DisengageRequest = NULL; pGKI_Initialize = NULL;
if (pGKI_CleanupRequest) pGKI_CleanupRequest();
pGKI_CleanupRequest = NULL;
LeaveCriticalSection(&GkiLock); DeleteCriticalSection(&GkiLock);
if (NULL != hwndGki) { DestroyWindow(hwndGki); } } // DeInitGkiManager()
HRESULT InitGkiManager(void) { HRESULT hr = CC_GKI_LOAD; InitializeCriticalSection(&GkiLock);
pGKI_RegistrationRequest = (PGKI_RegistrationRequest) GKI_RegistrationRequest; pGKI_UnregistrationRequest = (PGKI_UnregistrationRequest) GKI_UnregistrationRequest; pGKI_LocationRequest = (PGKI_LocationRequest) GKI_LocationRequest; pGKI_AdmissionRequest = (PGKI_AdmissionRequest) GKI_AdmissionRequest; pGKI_BandwidthRequest = (PGKI_BandwidthRequest) GKI_BandwidthRequest; pGKI_DisengageRequest = (PGKI_DisengageRequest) GKI_DisengageRequest; pGKI_CleanupRequest = (PGKI_CleanupRequest) GKI_CleanupRequest; pGKI_Initialize = (PGKI_Initialize) GKI_Initialize;
hr = pGKI_Initialize(); if(hr != GKI_OK) { DeleteCriticalSection(&GkiLock); DeInitGkiManager(); } else { fGKConfigured = TRUE; } return hr; } // InitGkiManager()
//
// Entry Points
//
HRESULT GkiFreeCall(PGKICALL pGkiCall) { HRESULT status = NOERROR; ASSERT(pGkiCall != NULL); ASSERT(pGkiCall->uGkiCallState != GCS_START); pGkiCall->hGkiCall = 0;
while (pGkiCall->pBwReqHead) { MemFree(BwReqDequeue(pGkiCall)); }
if (pGkiCall->pCalleeAliasNames) { Q931FreeAliasNames(pGkiCall->pCalleeAliasNames); pGkiCall->pCalleeAliasNames = NULL; }
if (pGkiCall->pCalleeExtraAliasNames != NULL) { Q931FreeAliasNames(pGkiCall->pCalleeExtraAliasNames); pGkiCall->pCalleeExtraAliasNames = NULL; }
switch (pGkiCall->uGkiCallState) { case GCS_START: case GCS_WAITING: break;
case GCS_ADMITTING: ASSERT(uGkiState == STATE_ADMITTING); switch (uGkiState) { case STATE_ADMITTING: uGkiState = STATE_REGISTERED; break; } // switch
break;
case GCS_ADMITTING_CLOSE_PENDING: ASSERT(uGkiState == STATE_ADMITTING || uGkiState == STATE_ADMITTING_UNREG || uGkiState == STATE_ADMITTING_REREG); switch (uGkiState) { case STATE_ADMITTING: uGkiState = STATE_REGISTERED; break; case STATE_ADMITTING_UNREG: uGkiState = STATE_REGISTERED; status = GkiUnregister(); break; case STATE_ADMITTING_REREG: uGkiState = STATE_REGISTERED; status = GkiRegister(); break; } // switch
break;
case GCS_ADMITTED: case GCS_CHANGING: case GCS_CHANGING_CLOSE_PENDING: case GCS_DISENGAGING: --uGkiCalls; ISRTRACE(ghISRInst, "GkiFreeCall: uGkiCalls = %d", uGkiCalls); break;
default: ISRERROR(ghISRInst, "GkiFreeCall: Invalid call state %d", pGkiCall->uGkiCallState); } // switch
pGkiCall->uGkiCallState = GCS_START;
if (uGkiCalls == 0 && uPendingDisengages == 0) { switch (uGkiState) { case STATE_DISENGAGING: uGkiState = STATE_REGISTERED; status = GkiUnregister(); break; case STATE_DISENGAGING_REREG: uGkiState = STATE_REGISTERED; status = GkiRegister(); break; } // switch
}
return status; } // GkiFreeCall()
HRESULT GkiCloseListen (CC_HLISTEN hListen) { register PLISTEN pListen; register HRESULT status; ISRTRACE(ghISRInst, StateName("GkiCloseListen <- State = %s", uGkiState), 0); EnterCriticalSection(&GkiLock);
pListen = ListenDequeue(hListen); if (pListen == NULL) { status = CC_GKI_LISTEN_NOT_FOUND; } else { if (pListen->pAliasNames) { FreeAliasNames(pListen->pAliasNames); } MemFree(pListen); if (pListenList) { status = GkiRegister(); } else { status = GkiUnregister(); } }
LeaveCriticalSection(&GkiLock); ISRTRACE(ghISRInst, StateName("GkiCloseListen -> State = %s", uGkiState), 0); return status; } // GkiCloseListen()
HRESULT GkiSetVendorConfig( PCC_VENDORINFO pVendorInfo, DWORD dwMultipointConfiguration) { HRESULT status = CC_OK;
EnterCriticalSection(&GkiLock); if(gpVendorInfo) { FreeVendorInfo(gpVendorInfo); gpVendorInfo = NULL; } if (!pVendorInfo) { // everything is cleaned up, so return
LeaveCriticalSection(&GkiLock); return status; } status = CopyVendorInfo(&gpVendorInfo, pVendorInfo); if (status != NOERROR) { ISRERROR(ghISRInst, "GkiSetRegistrationAliases: CopyVendorInfo returned 0x%x", status); LeaveCriticalSection(&GkiLock); return status; } g_dwMultipointConfiguration = dwMultipointConfiguration; LeaveCriticalSection(&GkiLock); return status; }
HRESULT GkiSetRegistrationAliases(PCC_ALIASNAMES pLocalAliasNames) { HRESULT status = CC_OK;
EnterCriticalSection(&GkiLock); if(gpLocalAliasNames) { FreeAliasNames(gpLocalAliasNames); gpLocalAliasNames = NULL; } if (!pLocalAliasNames) { // everything is cleaned up, so return
LeaveCriticalSection(&GkiLock); return status; } status = CopyAliasNames(&gpLocalAliasNames, pLocalAliasNames); if (status != NOERROR) { ISRERROR(ghISRInst, "GkiSetRegistrationAliases: CopyAliasNames returned 0x%x", status); LeaveCriticalSection(&GkiLock); return status; } LeaveCriticalSection(&GkiLock); return status; }
HRESULT GkiOpenListen (CC_HLISTEN hListen, PCC_ALIASNAMES pAliasNames, DWORD dwAddr, WORD wPort) { register PLISTEN pListen; register HRESULT status = NOERROR; ISRTRACE(ghISRInst, StateName("GkiOpenListen <- State = %s", uGkiState), 0); EnterCriticalSection(&GkiLock);
// dwAddr, wPort are in host byte order
// Check for invalid IP address
if (dwAddr == INADDR_ANY || dwAddr == INADDR_NONE) { // this doesn't neccessarily get the correct IP address on a multi-homed
// machine, but it at least tests to see if IP is configured on this
// box.
dwAddr = GetIpAddress(); if (dwAddr == INADDR_ANY) { LeaveCriticalSection(&GkiLock); return CC_GKI_IP_ADDRESS; } }
// Check for invalid alias list
if (pAliasNames) { PCC_ALIASITEM pAliasItem; unsigned int uIndex;
if (pAliasNames->wCount == 0) { ISRERROR(ghISRInst, "GkiOpenListen: Alias name wCount == 0", 0); return CC_BAD_PARAM; } pAliasItem = pAliasNames->pItems; for (uIndex = 0; uIndex < pAliasNames->wCount; ++uIndex, ++pAliasItem) { if (pAliasItem->wDataLength == 0 || pAliasItem->pData == NULL) { // Bad alias item
ISRERROR(ghISRInst, "GkiOpenListen: Bad alias item (wDataLength = %d)", pAliasItem->wDataLength); return CC_BAD_PARAM; } } }
pListen = (PLISTEN)MemAlloc(sizeof(*pListen)); if (pListen) { if (pAliasNames) { status = CopyAliasNames(&pListen->pAliasNames, pAliasNames); if (status != NOERROR) { ISRERROR(ghISRInst, "GkiOpenListen: CopyAliasNames returned 0x%x", status); LeaveCriticalSection(&GkiLock); MemFree(pListen); return status; } } else { pListen->pAliasNames = NULL; }
pListen->hListen = hListen; pListen->dwAddr = htonl(dwAddr); pListen->wPort = wPort; ListenEnqueue(pListen); if(GKIExists()) { status = GkiRegister(); } } // if
else { ISRERROR(ghISRInst, "GkiOpenListen: Could not allocate listen structure", 0); status = CC_NO_MEMORY; } // else
LeaveCriticalSection(&GkiLock); ISRTRACE(ghISRInst, StateName("GkiOpenListen -> State = %s", uGkiState), 0); return status; } // GkiOpenListen()
HRESULT GkiListenAddr (SOCKADDR_IN* psin) {
PLISTEN pListen = pListenList; HRESULT status = NOERROR;
SOCKADDR_IN srem; SOCKADDR_IN sloc;
ASSERT(psin); ASSERT(pListen != NULL);
// try and get the best interface given the dwAddr passed in to us
srem.sin_family = AF_INET; srem.sin_port = htons(7); // give echo a try since most GKs are unix-based
srem.sin_addr.s_addr = psin->sin_addr.s_addr;
status = NMGetBestInterface(&srem, &sloc);
if (status == NOERROR) { EnterCriticalSection(&GkiLock); while (pListen) { pListen->dwAddr = sloc.sin_addr.s_addr; pListen = pListen->pNext; } LeaveCriticalSection(&GkiLock); } return status; } // GkiListenAddr()
/*
* NOTES * Must have Call locked before calling! */
HRESULT GkiCloseCall(PGKICALL pGkiCall) { HRESULT status = NOERROR; ASSERT(GKIExists()); ASSERT(pGkiCall != NULL); ISRTRACE(ghISRInst, CallStateName("GkiCloseCall <- Call State = %s", pGkiCall->uGkiCallState), 0);
while (pGkiCall->pBwReqHead) { MemFree(BwReqDequeue(pGkiCall)); }
if (pGkiCall->uGkiCallState == GCS_START) { ISRWARNING(ghISRInst, CallStateName("GkiCloseCall: Call already in state %s", pGkiCall->uGkiCallState), 0); status = CC_GKI_CALL_STATE; } else { switch (uGkiState) { case STATE_START: break;
case STATE_REG_BYPASS: status = GkiFreeCall(pGkiCall); break;
default: switch (pGkiCall->uGkiCallState) { case GCS_WAITING: status = GkiFreeCall(pGkiCall); break;
case GCS_ADMITTING: pGkiCall->uGkiCallState = GCS_ADMITTING_CLOSE_PENDING; break;
case GCS_ADMITTING_CLOSE_PENDING: case GCS_CHANGING_CLOSE_PENDING: case GCS_DISENGAGING: ISRWARNING(ghISRInst, CallStateName("GkiCloseCall: Call already in closing state %s", pGkiCall->uGkiCallState), 0); status = CC_GKI_CALL_STATE; break;
case GCS_ADMITTED: pGkiCall->uGkiCallState = GCS_DISENGAGING; ISRTRACE(ghISRInst, "GKI_DisengageRequest called...", 0); ++uPendingDisengages; status = pGKI_DisengageRequest(pGkiCall->hGkiCall); if (status == NOERROR) { ISRTRACE(ghISRInst, GkiErrorName("GKI_DisengageRequest returned %s", status), 0); } else { --uPendingDisengages; ISRERROR(ghISRInst, GkiErrorName("GKI_DisengageRequest returned %s", status), 0); GkiFreeCall(pGkiCall); } break;
case GCS_CHANGING: pGkiCall->uGkiCallState = GCS_CHANGING_CLOSE_PENDING; break;
default: ISRERROR(ghISRInst, CallStateName("GkiCloseCall: Call in invalid state %s", pGkiCall->uGkiCallState), 0); status = CC_GKI_CALL_STATE; } // switch
} // switch
} // else
ISRTRACE(ghISRInst, StateName("GkiCloseCall -> State = %s", uGkiState), 0); return status; } // GkiCloseCall()
/*
* NOTES * Must have Call locked before calling! */
static HRESULT BandwidthRejected(PGKICALL pGkiCall, UINT Reason) { HRESULT status = NOERROR; PBWREQ pBwReq; CC_HCALL hCall;
ASSERT(pGkiCall != NULL); pBwReq = BwReqDequeue(pGkiCall); hCall = pGkiCall->hCall;
if (pBwReq) { if ((pGkiCall->uBandwidthUsed + pBwReq->uChannelBandwidth) <= pGkiCall->uBandwidthAllocated) { if (pBwReq->Type == TX) { OpenChannelConfirm (pBwReq->hChannel); } else { AcceptChannelConfirm(pBwReq->hChannel); } } else { if (pBwReq->Type == TX) { OpenChannelReject (pBwReq->hChannel, MapBandwidthRejectReason(Reason)); } else { AcceptChannelReject (pBwReq->hChannel, MapBandwidthRejectReason(Reason)); } } MemFree(pBwReq); if (ValidateCall(hCall) == NOERROR) { CheckPendingBandwidth(pGkiCall); } }
return status; } // BandwidthRejected()
/*
* NOTES * Must have Call locked before calling! */
static HRESULT CheckPendingBandwidth(PGKICALL pGkiCall) { HRESULT status = NOERROR; PBWREQ pBwReq; CC_HCALL hCall;
ASSERT(pGkiCall != NULL); ASSERT(pGkiCall->uGkiCallState == GCS_ADMITTED); hCall = pGkiCall->hCall;
while (pGkiCall->pBwReqHead != NULL && (pGkiCall->uBandwidthUsed + pGkiCall->pBwReqHead->uChannelBandwidth) <= pGkiCall->uBandwidthAllocated) { pBwReq = BwReqDequeue(pGkiCall); ASSERT(pBwReq != NULL); pGkiCall->uBandwidthUsed += pBwReq->uChannelBandwidth; if (pBwReq->Type == TX) { OpenChannelConfirm(pBwReq->hChannel); } else { AcceptChannelConfirm(pBwReq->hChannel); } MemFree(pBwReq); if (ValidateCall(hCall) != NOERROR) { return status; } }
if (pGkiCall->pBwReqHead != NULL) { pGkiCall->uGkiCallState = GCS_CHANGING; ISRTRACE(ghISRInst, "GKI_BandwidthRequest called...", 0); status = pGKI_BandwidthRequest(pGkiCall->hGkiCall, pGkiCall->usCallTypeChoice, pGkiCall->uBandwidthUsed + pGkiCall->pBwReqHead->uChannelBandwidth); if (status == NOERROR) { ISRTRACE(ghISRInst, GkiErrorName("GKI_BandwidthRequest returned %s", status), 0); } else { ISRERROR(ghISRInst, GkiErrorName("GKI_BandwidthRequest returned %s", status), 0); BandwidthRejected(pGkiCall, BndRjctRsn_undfndRsn_chosen); } }
return status; } // CheckPendingBandwidth()
static void FreeAliasList(SeqAliasAddr *pAliasAddrs) { register SeqAliasAddr *pAlias = pAliasAddrs; while (pAlias) { if (pAlias->value.choice == h323_ID_chosen && pAlias->value.u.h323_ID.value) MemFree(pAlias->value.u.h323_ID.value); pAlias = pAlias->next; } MemFree(pAlias); } // FreeAliasList()
/*
* NOTES * Must have Call locked before calling! * * The following fields in the GKICALL structure must be properly filled * in before calling this function: * pCall Pointer back to containing CALL structure. * CallType Type of call. * uBandwidthRequested Initial bandwidth for call. * pConferenceId Pointer to conference ID buffer. * bActiveMC TRUE if calling party has an active MC. * bAnswerCall ??? * CallIdentifier the GUID identifying this call. This must be the same * value as CallIdentifier of the Q.931 messages. */
HRESULT GkiOpenCall (PGKICALL pGkiCall, void *pConference) { HRESULT status = NOERROR; CC_HCALL hCall; TransportAddress DestCallSignalAddress; TransportAddress * pDestCallSignalAddress; SeqAliasAddr * pAliasAddrs; SeqAliasAddr * pExtraAliasAddrs; SeqAliasAddr * pAlias; PCC_ALIASITEM pAliasItem; unsigned uCount; unsigned uIndex; ConferenceIdentifier ConferenceId;
ASSERT(GKIExists()); ASSERT(pGkiCall != NULL); ASSERT(pConference != NULL); ISRTRACE(ghISRInst, StateName("GkiOpenCall <- State = %s", uGkiState), 0); EnterCriticalSection(&GkiLock);
switch (uGkiState) { case STATE_REG_BYPASS: ASSERT(pGkiCall->uGkiCallState == GCS_START || pGkiCall->uGkiCallState == GCS_WAITING || pGkiCall->uGkiCallState == GCS_ADMITTING); hCall = pGkiCall->hCall; GkiAllocCall(pGkiCall, GKI_BYPASS_HANDLE); pGkiCall->uBandwidthAllocated = MAX_BANDWIDTH; if (pGkiCall->bAnswerCall) { status = AcceptCallConfirm(pGkiCall->pCall, pConference); if (status == NOERROR && ValidateCall(hCall) == NOERROR) { CheckPendingBandwidth(pGkiCall); } } else if (pGkiCall->dwIpAddress == 0) { status = PlaceCallReject (pGkiCall->pCall, pConference, CC_INVALID_WITHOUT_GATEKEEPER); } else { status = PlaceCallConfirm (pGkiCall->pCall, pConference); if (status == NOERROR && ValidateCall(hCall) == NOERROR) { CheckPendingBandwidth(pGkiCall); } } break;
case STATE_REGISTERING: case STATE_REGISTERING_REREG: case STATE_ADMITTING: pGkiCall->uGkiCallState = GCS_WAITING; break;
case STATE_REGISTERED: switch (pGkiCall->CallType) { case POINT_TO_POINT: pGkiCall->usCallTypeChoice = pointToPoint_chosen; break; case ONE_TO_MANY: pGkiCall->usCallTypeChoice = oneToN_chosen; break; case MANY_TO_ONE: pGkiCall->usCallTypeChoice = nToOne_chosen; break; case MANY_TO_MANY: pGkiCall->usCallTypeChoice = nToN_chosen; break; default: LeaveCriticalSection(&GkiLock); ISRERROR(ghISRInst, "GkiOpenCall -> Invalid CallType %d", pGkiCall->CallType); return CC_BAD_PARAM; } // switch
pDestCallSignalAddress = NULL; pAliasAddrs = NULL; pExtraAliasAddrs = NULL;
if (pGkiCall->dwIpAddress != 0 && pGkiCall->wPort != 0) { DestCallSignalAddress.choice = ipAddress_chosen; DestCallSignalAddress.u.ipAddress.ip.length = 4; *((DWORD *)DestCallSignalAddress.u.ipAddress.ip.value) = pGkiCall->dwIpAddress; DestCallSignalAddress.u.ipAddress.port = pGkiCall->wPort; pDestCallSignalAddress = &DestCallSignalAddress; }
if (pGkiCall->pCalleeAliasNames) { uCount = pGkiCall->pCalleeAliasNames->wCount; pAliasAddrs = MemAlloc(uCount * sizeof(*pAliasAddrs)); if (pAliasAddrs == NULL) { LeaveCriticalSection(&GkiLock); ISRERROR(ghISRInst, "GkiOpenCall: Could not allocate %d Alias Addresses", uCount); return CC_NO_MEMORY; } memset(pAliasAddrs, 0, uCount * sizeof(*pAliasAddrs)); pAlias = pAliasAddrs; pAliasItem = pGkiCall->pCalleeAliasNames->pItems; for (uIndex = 0; uIndex < uCount; ++uIndex) { status = CopyAliasItem(pAlias, pAliasItem); if (status != NOERROR) { LeaveCriticalSection(&GkiLock); ISRERROR(ghISRInst, "GkiOpenCall: CopyAliasItem returned %d", status); FreeAliasList(pAliasAddrs); MemFree(pAliasAddrs); return status; } pAlias->next = pAlias + 1; ++pAlias; ++pAliasItem; } // for
--pAlias; pAlias->next = NULL; }
if (pGkiCall->pCalleeExtraAliasNames) { uCount = pGkiCall->pCalleeExtraAliasNames->wCount; pExtraAliasAddrs = MemAlloc(uCount * sizeof(*pExtraAliasAddrs)); if (pExtraAliasAddrs == NULL) { LeaveCriticalSection(&GkiLock); ISRERROR(ghISRInst, "GkiOpenCall: Could not allocate %d Alias Addresses", uCount); if (pAliasAddrs) { FreeAliasList(pAliasAddrs); MemFree(pAliasAddrs); } return CC_NO_MEMORY; } memset(pExtraAliasAddrs, 0, uCount * sizeof(*pExtraAliasAddrs)); pAlias = pExtraAliasAddrs; pAliasItem = pGkiCall->pCalleeExtraAliasNames->pItems; for (uIndex = 0; uIndex < uCount; ++uIndex) { status = CopyAliasItem(pAlias, pAliasItem); if (status != NOERROR) { LeaveCriticalSection(&GkiLock); ISRERROR(ghISRInst, "GkiOpenCall: CopyAliasItem returned %d", status); if (pAliasAddrs) { FreeAliasList(pAliasAddrs); MemFree(pAliasAddrs); } FreeAliasList(pExtraAliasAddrs); MemFree(pExtraAliasAddrs); return status; } pAlias->next = pAlias + 1; ++pAlias; ++pAliasItem; } // for
--pAlias; pAlias->next = NULL; }
if (pGkiCall->uBandwidthRequested < MIN_BANDWIDTH) { pGkiCall->uBandwidthRequested = MIN_BANDWIDTH; } ASSERT(pGkiCall->uBandwidthAllocated == 0); ASSERT(pGkiCall->uBandwidthUsed == 0);
memcpy(ConferenceId.value, pGkiCall->pConferenceId, 16); if (((DWORD *)pGkiCall->pConferenceId)[0] != 0 || ((DWORD *)pGkiCall->pConferenceId)[1] != 0 || ((DWORD *)pGkiCall->pConferenceId)[2] != 0 || ((DWORD *)pGkiCall->pConferenceId)[3] != 0) { ConferenceId.length = 16; } else { ConferenceId.length = 0; }
pGkiCall->hGkiCall = GKI_ADMITTING_HANDLE; if (pDestCallSignalAddress != NULL || pAliasAddrs != NULL) { uGkiState = STATE_ADMITTING; pGkiCall->uGkiCallState = GCS_ADMITTING; ISRTRACE(ghISRInst, "GKI_AdmissionRequest called...", 0); status = pGKI_AdmissionRequest(pGkiCall->usCallTypeChoice, // usCallTypeChoice.
pAliasAddrs, // pDestinationInfo,
pDestCallSignalAddress, // pDestCallSignalAddress
pExtraAliasAddrs, // pDestExtraCallInfo,
&pGkiCall->CallIdentifier, // H.225 call identifer
pGkiCall->uBandwidthRequested, // bandWidth,
&ConferenceId, // pConferenceID,
pGkiCall->bActiveMC, // activeMC,
pGkiCall->bAnswerCall, // answerCall,
ipAddress_chosen); // usCallTransport
if (status == NOERROR) { ISRTRACE(ghISRInst, GkiErrorName("GKI_AdmissionRequest returned %s", status), 0); } else { ISRERROR(ghISRInst, GkiErrorName("GKI_AdmissionRequest returned %s", status), 0); } } else { pGkiCall->hGkiCall = 0; status = CC_BAD_PARAM; }
if (status != NOERROR) { uGkiState = STATE_REGISTERED; GkiCancelCall(pGkiCall, pConference); }
if (pAliasAddrs) { FreeAliasList(pAliasAddrs); MemFree(pAliasAddrs); }
if (pExtraAliasAddrs) { FreeAliasList(pExtraAliasAddrs); MemFree(pExtraAliasAddrs); } break;
case STATE_START: case STATE_CLASS_REGISTERED: case STATE_WINDOW_CREATED: pGkiCall->uGkiCallState = GCS_WAITING; // not registered!!! attempt to register or reregister
status = GkiRegister(); break;
default: ISRERROR(ghISRInst, StateName("GkiOpenCall: Invalid state %s", uGkiState), 0); status = LastGkiError; } // switch
LeaveCriticalSection(&GkiLock); ISRTRACE(ghISRInst, CallStateName("GkiOpenCall -> Call State = %s", pGkiCall->uGkiCallState), 0); return status; } // GkiOpenCall()
/*
* NOTES * Must have Call locked before calling! */
HRESULT GkiOpenChannel(PGKICALL pGkiCall, unsigned uChannelBandwidth, CC_HCHANNEL hChannel, CHANNELTYPE Type) { HRESULT status = NOERROR; PBWREQ pBwReq; ASSERT(GKIExists()); ASSERT(pGkiCall != NULL); ISRTRACE(ghISRInst, CallStateName("GkiOpenChannel <- Call State = %s", pGkiCall->uGkiCallState), 0);
pBwReq = (PBWREQ)MemAlloc(sizeof(*pBwReq)); if (pBwReq == NULL) { ISRERROR(ghISRInst, "GkiOpenChannel: Memory allocation failed", 0); return CC_NO_MEMORY; }
pBwReq->uChannelBandwidth = uChannelBandwidth / 100; pBwReq->hChannel = hChannel; pBwReq->Type = Type; BwReqEnqueue(pGkiCall, pBwReq); switch (pGkiCall->uGkiCallState) { case GCS_WAITING: case GCS_ADMITTING: case GCS_CHANGING: // Must wait for current operation to complete
break;
case GCS_ADMITTED: status = CheckPendingBandwidth(pGkiCall); break;
default: ISRERROR(ghISRInst, "GkiOpenChannel: Invalid call state %d", pGkiCall->uGkiCallState); status = CC_GKI_CALL_STATE; } // switch
ISRTRACE(ghISRInst, CallStateName("GkiOpenChannel -> Call State = %s", pGkiCall->uGkiCallState), 0); return status; } // GkiOpenChannel()
/*
* NOTES * Must have Call locked before calling! */
HRESULT GkiCloseChannel(PGKICALL pGkiCall, unsigned uChannelBandwidth, CC_HCHANNEL hChannel) { PBWREQ pBwReq; PBWREQ pBwReq1; ASSERT(GKIExists()); ASSERT(pGkiCall != NULL); ISRTRACE(ghISRInst, CallStateName("GkiCloseChannel <- Call State = %s", pGkiCall->uGkiCallState), 0);
// If Bandwidth request is still in queue, bandwidth has not been allocated
pBwReq = pGkiCall->pBwReqHead; if (pBwReq) { if (pBwReq->hChannel == hChannel) { MemFree(BwReqDequeue(pGkiCall)); ISRTRACE(ghISRInst, CallStateName("GkiCloseChannel -> Call State = %s", pGkiCall->uGkiCallState), 0); return NOERROR; } while ((pBwReq1 = pBwReq->pNext) != NULL) { if (pBwReq1->hChannel == hChannel) { if (pGkiCall->pBwReqTail == pBwReq1) { pGkiCall->pBwReqTail = pBwReq; } pBwReq->pNext = pBwReq1->pNext; MemFree(pBwReq1); ISRTRACE(ghISRInst, CallStateName("GkiCloseChannel -> Call State = %s", pGkiCall->uGkiCallState), 0); return NOERROR; } } }
pGkiCall->uBandwidthUsed -= (uChannelBandwidth / 100); ISRTRACE(ghISRInst, CallStateName("GkiCloseChannel -> Call State = %s", pGkiCall->uGkiCallState), 0); return NOERROR; } // GkiCloseChannel()
unsigned GkiGetBandwidth(PGKICALL pGkiCall) { ASSERT(pGkiCall != NULL); return pGkiCall->uBandwidthAllocated * 100; } // GkiGetBandwidth()
//
// GkiWndProc subroutines
//
/*
* NOTES * Must have Call locked before calling! */
static HRESULT CheckPendingOpen(PGKICALL pGkiCall, void *pConference) { HRESULT status = NOERROR;
ASSERT(pGkiCall != NULL); ASSERT(pConference != NULL);
switch (uGkiState) { case STATE_REGISTERED: case STATE_REG_BYPASS: // TBD - Can only open 1!!!
ASSERT(pGkiCall->uGkiCallState != GCS_ADMITTING); if (pGkiCall->uGkiCallState == GCS_WAITING) { status = GkiOpenCall(pGkiCall, pConference); } break;
default: status = LastGkiError; } // switch
return status; } // CheckPendingOpen()
static void GkiNoResponse(HWND hWnd) { HRESULT status;
switch (uGkiState) { case STATE_START: case STATE_CLASS_REGISTERED: case STATE_WINDOW_CREATED: case STATE_REG_BYPASS: break;
case STATE_REGISTERING: case STATE_REGISTERING_REREG: case STATE_REGISTERING_UNREG: #if(0)
why did Intel *DO* this????? ISRTRACE(ghISRInst, "GkiWndProc: dummy GKI_REG_REJECT", 0); PostMessage(hWnd, GKIMAN_BASE + GKI_REG_REJECT, 0, 0); #else
// there was no response to registration request, assume the GK is not there or dead.
uGkiState = STATE_REG_BYPASS; if(gpRasNotifyProc) { (gpRasNotifyProc)(RAS_REG_TIMEOUT, 0); } ApplyToAllCalls(CheckPendingOpen); #endif
break;
case STATE_ADMITTING: case STATE_ADMITTING_REREG: ApplyToAllCalls(GkiCancelAdmitting); uGkiState = STATE_REGISTERED;
// Fall-through to next case
case STATE_REGISTERED: if (uGkiCalls == 0) { GkiRegister(); } else { uGkiState = STATE_REG_BYPASS; ApplyToAllCalls(GatekeeperNotFound); ISRTRACE(ghISRInst, "GKI_UnregistrationRequest called...", 0); status = pGKI_UnregistrationRequest(); if (status == NOERROR) { ISRTRACE(ghISRInst, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0); } else { ISRERROR(ghISRInst, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0); } } break;
case STATE_ADMITTING_UNREG: ApplyToAllCalls(GkiCancelAdmitting); uGkiState = STATE_REGISTERED; GkiUnregister(); break;
case STATE_DISENGAGING: ApplyToAllCalls(GatekeeperNotFound); ASSERT(uGkiCalls == 0); uGkiState = STATE_REGISTERED; GkiUnregister(); break;
case STATE_DISENGAGING_REREG: ApplyToAllCalls(GatekeeperNotFound); ASSERT(uGkiCalls == 0); uGkiState = STATE_REGISTERED; GkiRegister(); break;
case STATE_UNREGISTERING: case STATE_UNREGISTERING_REREG: ISRTRACE(ghISRInst, "GkiWndProc: dummy GKI_UNREG_CONFIRM", 0); PostMessage(hWnd, GKIMAN_BASE + GKI_UNREG_CONFIRM, 0, 0); break;
default: ISRERROR(ghISRInst, "GkiWndProc: Bad uGkiState %d", uGkiState); } // switch
} // GkiNoResponse()
LRESULT APIENTRY GkiWndProc( HWND hWnd, /* window handle */ UINT message, /* type of message */ WPARAM wParam, /* additional information */ LPARAM lParam) /* additional information */ { CallReturnInfo * pCallReturnInfo; PGKICALL pGkiCall; void * pConference; CC_HCALL hCall; CC_HCONFERENCE hConference; HRESULT status; if (message < GKIMAN_BASE) { return DefWindowProc(hWnd, message, wParam, lParam); }
EnterCallControlTop();
ISRTRACE(ghISRInst, StateName("GkiWndProc <- State = %s", uGkiState), 0);
switch (message) { case GKIMAN_BASE + GKI_REG_CONFIRM: ISRTRACE(ghISRInst, "GkiWndProc: GKI_REG_CONFIRM", 0); ASSERT(gpRasNotifyProc); // we should never get messages if
// this is not configured
if(gpRasNotifyProc) { (gpRasNotifyProc)(RAS_REG_CONFIRM, 0); } switch (uGkiState) { case STATE_REGISTERING: uGkiState = STATE_REGISTERED; ApplyToAllCalls(CheckPendingOpen); break; case STATE_REGISTERING_REREG: uGkiState = STATE_REGISTERED; GkiRegister(); break; case STATE_REGISTERING_UNREG: uGkiState = STATE_REGISTERED; GkiUnregister(); break; default: ISRERROR(ghISRInst, StateName("GkiWndProc: GKI_REG_CONFIRM in state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_REG_DISCOVERY: ISRTRACE(ghISRInst, "GkiWndProc: GKI_REG_DISCOVERY", 0); ASSERT(uGkiState == STATE_REGISTERING || uGkiState == STATE_REGISTERING_REREG || uGkiState == STATE_REGISTERING_UNREG); break;
case GKIMAN_BASE + GKI_UNREG_REQUEST: // the GK kicked us out!
// pass the unregistration request upward
ASSERT(gpRasNotifyProc); // we should never get messages if
// this is not configured
if(gpRasNotifyProc) { (gpRasNotifyProc)(RAS_UNREG_REQ, MapUnregistrationRequestReason((UINT)wParam)); } break;
case GKIMAN_BASE + GKI_REG_REJECT: ISRERROR(ghISRInst, "GkiWndProc: GKI_REG_REJECT Reason = %d", (DWORD)wParam); switch (uGkiState) { case STATE_REGISTERING: ApplyToAllCalls(GkiCancelCall); #if(0)
// leave the listen list intact so that subsequent registration attempts
// will work.
//
EnterCriticalSection(&GkiLock); while (pListenList) { register PLISTEN pListen = pListenList; pListenList = pListen->pNext; LeaveCriticalSection(&GkiLock); ListenReject(pListen->hListen, MapRegistrationRejectReason((UINT)wParam)); if (pListen->pAliasNames) { FreeAliasNames(pListen->pAliasNames); } MemFree(pListen); EnterCriticalSection(&GkiLock); } LeaveCriticalSection(&GkiLock); #endif
uGkiState = STATE_WINDOW_CREATED;
// pass the registration reject upward
ASSERT(gpRasNotifyProc); // we should never get messages if
// this is not configured
if(gpRasNotifyProc) { (gpRasNotifyProc)(RAS_REJECTED, MapRegistrationRejectReason((UINT)wParam)); }
break; case STATE_REGISTERING_REREG: uGkiState = STATE_WINDOW_CREATED; GkiRegister(); break; case STATE_REGISTERING_UNREG: uGkiState = STATE_WINDOW_CREATED; GkiUnregister(); break; default: ISRERROR(ghISRInst, StateName("GkiWndProc: GKI_REG_REJECT in state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_REG_BYPASS: ISRTRACE(ghISRInst, "GkiWndProc: GKI_REG_BYPASS", 0); switch (uGkiState) { case STATE_REGISTERING: case STATE_REGISTERING_REREG: uGkiState = STATE_REG_BYPASS; ApplyToAllCalls(CheckPendingOpen); break; case STATE_REGISTERING_UNREG: uGkiState = STATE_WINDOW_CREATED; GkiUnregister(); break; default: ISRERROR(ghISRInst, StateName("GkiWndProc: GKI_REG_BYPASS in state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_UNREG_CONFIRM: ISRTRACE(ghISRInst, "GkiWndProc: GKI_UNREG_CONFIRM", 0); ASSERT(gpRasNotifyProc); // we should never get messages if
// this is not configured
if(gpRasNotifyProc) { (gpRasNotifyProc)(RAS_UNREG_CONFIRM, 0); }
switch (uGkiState) { case STATE_REGISTERING: case STATE_REGISTERING_REREG: case STATE_REGISTERED: case STATE_ADMITTING: case STATE_ADMITTING_REREG: case STATE_DISENGAGING_REREG: case STATE_UNREGISTERING_REREG: uGkiState = STATE_WINDOW_CREATED; GkiRegister(); break;
default: ISRERROR(ghISRInst, StateName("GkiWndProc: GKI_UNREG_CONFIRM in state %s", uGkiState), 0);
// Fall through to next case
case STATE_ADMITTING_UNREG: case STATE_DISENGAGING: ApplyToAllCalls(GkiCancelCall);
// Fall-through to next case
case STATE_REGISTERING_UNREG: case STATE_UNREGISTERING: uGkiState = STATE_WINDOW_CREATED;
// Fall-through to next case
case STATE_CLASS_REGISTERED: case STATE_WINDOW_CREATED:
// Fall-through to next case
case STATE_START: case STATE_REG_BYPASS: break;
} // switch
break;
case GKIMAN_BASE + GKI_UNREG_REJECT: ISRERROR(ghISRInst, "GkiWndProc: GKI_UNREG_REJECT Reason = %d", (DWORD)wParam); switch (uGkiState) { case STATE_UNREGISTERING: uGkiState = STATE_WINDOW_CREATED; GkiUnregister(); break; case STATE_UNREGISTERING_REREG: uGkiState = STATE_WINDOW_CREATED; GkiRegister(); break; default: ISRWARNING(ghISRInst, StateName("GkiWndProc: GKI_UNREG_REJECT in state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_ADM_CONFIRM: ISRTRACE(ghISRInst, "GkiWndProc: GKI_ADM_CONFIRM", 0); switch (uGkiState) { case STATE_ADMITTING: uGkiState = STATE_REGISTERED; pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(GKI_ADMITTING_HANDLE, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { ISRTRACE(ghISRInst, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0); pGkiCall->usCallModelChoice = pCallReturnInfo->callModel.choice; pGkiCall->uBandwidthAllocated = pCallReturnInfo->bandWidth; pGkiCall->usCRV = pCallReturnInfo->callReferenceValue; memcpy(pGkiCall->pConferenceId, pCallReturnInfo->conferenceID.value, 16); switch (pGkiCall->uGkiCallState) { case GCS_ADMITTING: GkiAllocCall(pGkiCall, pCallReturnInfo->hCall); if (pGkiCall->bAnswerCall) { status = AcceptCallConfirm(pGkiCall->pCall, pConference); } else { ASSERT(pCallReturnInfo->destCallSignalAddress.choice == ipAddress_chosen); pGkiCall->dwIpAddress = *((DWORD *)pCallReturnInfo->destCallSignalAddress.u.ipAddress.ip.value); pGkiCall->wPort = pCallReturnInfo->destCallSignalAddress.u.ipAddress.port; status = PlaceCallConfirm(pGkiCall->pCall, pConference); } if (status == NOERROR && ValidateCall(hCall) == NOERROR) CheckPendingBandwidth(pGkiCall); break;
case GCS_ADMITTING_CLOSE_PENDING: GkiAllocCall(pGkiCall, pCallReturnInfo->hCall); GkiCloseCall(pGkiCall); break;
default: ISRWARNING(ghISRInst, CallStateName("GkiWndProc: GKI_ADM_CONFIRM in call state %s", pGkiCall->uGkiCallState), 0); } // switch
UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_ADM_CONFIRM handle not found", 0); } ApplyToAllCalls(CheckPendingOpen); break;
case STATE_ADMITTING_UNREG: uGkiState = STATE_REGISTERED; GkiUnregister(); break;
default: ISRWARNING(ghISRInst, StateName("GkiWndProc: GKI_ADM_CONFIRM in state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_ADM_REJECT: ISRERROR(ghISRInst, "GkiWndProc: GKI_ADM_REJECT Reason = %d", (DWORD)wParam); switch (uGkiState) { case STATE_ADMITTING: pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(GKI_ADMITTING_HANDLE, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { ASSERT(pGkiCall->uGkiCallState == GCS_ADMITTING); switch (wParam) { case AdmissionRejectReason_calledPartyNotRegistered_chosen: if (pGkiCall->bAnswerCall) { // The gateway has gone away and come back without our notice!
GkiCancelAdmitting(pGkiCall, pConference); uGkiState = STATE_REGISTERED; GkiRegister(); ISRTRACE(ghISRInst, StateName("GkiWndProc -> State = %s", uGkiState), 0); LeaveCallControlTop(0); } break; case AdmissionRejectReason_callerNotRegistered_chosen: if (pGkiCall->bAnswerCall == FALSE) { // The gateway has gone away and come back without our notice!
GkiCancelAdmitting(pGkiCall, pConference); uGkiState = STATE_REGISTERED; GkiRegister(); ISRTRACE(ghISRInst, StateName("GkiWndProc -> State = %s", uGkiState), 0); LeaveCallControlTop(0); } } // switch
GkiFreeCall(pGkiCall); if (pGkiCall->bAnswerCall) AcceptCallReject(pGkiCall->pCall, pConference, MapAdmissionRejectReason((UINT)wParam)); else PlaceCallReject (pGkiCall->pCall, pConference, MapAdmissionRejectReason((UINT)wParam)); UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_ADM_REJECT handle not found", 0); } uGkiState = STATE_REGISTERED; ApplyToAllCalls(CheckPendingOpen); break;
case STATE_ADMITTING_REREG: pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(GKI_ADMITTING_HANDLE, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { ASSERT(pGkiCall->uGkiCallState == GCS_ADMITTING_CLOSE_PENDING); GkiFreeCall(pGkiCall); if (pGkiCall->bAnswerCall) { AcceptCallReject(pGkiCall->pCall, pConference, MapAdmissionRejectReason((UINT)wParam)); } else { PlaceCallReject (pGkiCall->pCall, pConference, MapAdmissionRejectReason((UINT)wParam)); } UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_ADM_REJECT handle not found", 0); } uGkiState = STATE_REGISTERED; GkiRegister(); break;
case STATE_ADMITTING_UNREG: pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(GKI_ADMITTING_HANDLE, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { ASSERT(pGkiCall->uGkiCallState == GCS_ADMITTING_CLOSE_PENDING); GkiFreeCall(pGkiCall); if (pGkiCall->bAnswerCall) { AcceptCallReject(pGkiCall->pCall, pConference, MapAdmissionRejectReason((UINT)wParam)); } else { PlaceCallReject (pGkiCall->pCall, pConference, MapAdmissionRejectReason((UINT)wParam)); } UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_ADM_REJECT handle not found", 0); } uGkiState = STATE_REGISTERED; GkiUnregister(); break;
default: ISRWARNING(ghISRInst, StateName("GkiWndProc: GKI_ADM_REJECT in state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_BW_CONFIRM: ISRTRACE(ghISRInst, "GkiWndProc: GKI_BW_CONFIRM", 0); switch (uGkiState) { case STATE_REGISTERED: pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(pCallReturnInfo->hCall, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { ISRTRACE(ghISRInst, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0); pGkiCall->uBandwidthAllocated = pCallReturnInfo->bandWidth; switch (pGkiCall->uGkiCallState) { case GCS_ADMITTED: if (pGkiCall->uBandwidthUsed < pGkiCall->uBandwidthAllocated) { BandwidthShrunk(pGkiCall->pCall, pConference, pGkiCall->uBandwidthAllocated, ((long)pGkiCall->uBandwidthAllocated) - ((long)pGkiCall->uBandwidthUsed)); } break;
case GCS_CHANGING: pGkiCall->uGkiCallState = GCS_ADMITTED; CheckPendingBandwidth(pGkiCall); break;
case GCS_CHANGING_CLOSE_PENDING: pGkiCall->uGkiCallState = GCS_ADMITTED; GkiCloseCall(pGkiCall); break;
default: ISRWARNING(ghISRInst, CallStateName("GkiWndProc: GKI_BW_CONFIRM in call state %s", pGkiCall->uGkiCallState), 0); } // switch
UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_BW_CONFIRM handle not found", 0); } // else
break;
default: ISRERROR(ghISRInst, StateName("GkiWndProc: GKI_BW_CONFIRM in GKI state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_BW_REJECT: ISRERROR(ghISRInst, "GkiWndProc: GKI_BW_REJECT Reason = %d", (DWORD)wParam); switch (uGkiState) { case STATE_REGISTERED: pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(pCallReturnInfo->hCall, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { ISRTRACE(ghISRInst, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0); pGkiCall->uBandwidthAllocated = pCallReturnInfo->bandWidth; switch (pGkiCall->uGkiCallState) { case GCS_CHANGING: pGkiCall->uGkiCallState = GCS_ADMITTED; BandwidthRejected(pGkiCall, (UINT)wParam); if (ValidateCall(hCall) == NOERROR) { CheckPendingBandwidth(pGkiCall); } break;
case GCS_CHANGING_CLOSE_PENDING: pGkiCall->uGkiCallState = GCS_ADMITTED; GkiCloseCall(pGkiCall); break;
default: ISRERROR(ghISRInst, CallStateName("GkiWndProc: GKI_BW_REJECT in state %s", pGkiCall->uGkiCallState), 0); } // switch
UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_BW_REJECT handle not found", 0); } break;
default: ISRERROR(ghISRInst, StateName("GkiWndProc: GKI_BW_REJECT in state %s", uGkiState), 0); } // switch
break;
case GKIMAN_BASE + GKI_DISENG_CONFIRM: ISRTRACE(ghISRInst, "GkiWndProc: GKI_DISENG_CONFIRM", 0); if (LockGkiCall((HANDLE)lParam, &pGkiCall) == NOERROR) { ISRTRACE(ghISRInst, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0); switch (pGkiCall->uGkiCallState) { case GCS_DISENGAGING: --uPendingDisengages; break;
default: ISRWARNING(ghISRInst, CallStateName("GkiWndProc: GKI_DISENG_CONFIRM in call state %s", pGkiCall->uGkiCallState), 0); } // switch
GkiFreeCall(pGkiCall); Disengage(pGkiCall->pCall); } // if
else if (uPendingDisengages != 0) { --uPendingDisengages; if (uPendingDisengages == 0) { switch (uGkiState) { case STATE_DISENGAGING: uGkiState = STATE_REGISTERED; GkiUnregister(); break; case STATE_DISENGAGING_REREG: uGkiState = STATE_REGISTERED; GkiRegister(); break; } // switch
} // if
} // else if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_DISENG_CONFIRM handle not found", 0); } break;
case GKIMAN_BASE + GKI_DISENG_REJECT: ISRERROR(ghISRInst, "GkiWndProc: GKI_DISENG_REJECT Reason = %d", (DWORD)wParam); if (LockGkiCall((HANDLE)lParam, &pGkiCall) == NOERROR) { ISRTRACE(ghISRInst, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0); switch (pGkiCall->uGkiCallState) { case GCS_DISENGAGING: // Pretend we received a Disengage Confirm
--uPendingDisengages; break;
default: ISRERROR(ghISRInst, CallStateName("GkiWndProc: GKI_DISENG_REJECT in call state %s", pGkiCall->uGkiCallState), 0); } // switch
GkiFreeCall(pGkiCall); Disengage(pGkiCall->pCall); } // if
else if (uPendingDisengages != 0) { // Pretend we received a Disengage Confirm
--uPendingDisengages; if (uPendingDisengages == 0) { switch (uGkiState) { case STATE_DISENGAGING: uGkiState = STATE_REGISTERED; GkiUnregister(); break; case STATE_DISENGAGING_REREG: uGkiState = STATE_REGISTERED; GkiRegister(); break; } // switch
} // if
} // else if
else { ISRWARNING(ghISRInst, "GkiWndProc: GKI_DISENG_REJECT handle not found", 0); } break;
case GKIMAN_BASE + GKI_LOCATION_CONFIRM: ISRTRACE(ghISRInst, "GkiWndProc: GKI_LOCATION_CONFIRM", 0); break;
case GKIMAN_BASE + GKI_LOCATION_REJECT: ISRERROR(ghISRInst, "GkiWndProc: GKI_LOCATION_REJECT Reason = %d", (DWORD)wParam); break;
case GKIMAN_BASE + GKI_ERROR: ISRERROR(ghISRInst, GkiErrorName("GkiWndProc: GKI_ERROR %s %%d", (HRESULT)lParam), (DWORD)wParam); switch (lParam) { case GKI_NO_RESPONSE: LastGkiError = (HRESULT)lParam; GkiNoResponse(hWnd); break; #if 1
// TEMPORARY KLUDGE FOR WINSOCK 2 BETA 1.6 OPERATION
case MAKE_CUSTOM_HRESULT(SEVERITY_ERROR,1,FACILITY_WINSOCK,0xffff): uGkiState = STATE_REG_BYPASS; ApplyToAllCalls(CheckPendingOpen); break; #endif
default: LastGkiError = (HRESULT)lParam; GkiUnregister(); } // switch
break;
default: ISRERROR(ghISRInst, "Unknown message %d", message); } // switch
ISRTRACE(ghISRInst, StateName("GkiWndProc -> State = %s", uGkiState), 0); LeaveCallControlTop(0); } // GkiWndProc()
// because the ASN.1 header files are not exposed and there is a redefinition of
// RAS reason codes, make sure that the mapping is correct. The functions herien
// assume equality and don't actually do any remapping.
// break the build if the definitions don't match !!!
#if (discoveryRequired_chosen != RRJ_DISCOVERY_REQ)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (RegistrationRejectReason_invalidRevision_chosen != RRJ_INVALID_REVISION)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (invalidCallSignalAddress_chosen != RRJ_INVALID_CALL_ADDR)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (invalidRASAddress_chosen != RRJ_INVALID_RAS_ADDR)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (duplicateAlias_chosen != RRJ_DUPLICATE_ALIAS)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (invalidTerminalType_chosen != RRJ_INVALID_TERMINAL_TYPE)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (RegistrationRejectReason_undefinedReason_chosen != RRJ_UNDEFINED)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (transportNotSupported_chosen != RRJ_TRANSPORT_NOT_SUPPORTED)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (transportQOSNotSupported_chosen != RRJ_TRANSPORT_QOS_NOT_SUPPORTED)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (RegistrationRejectReason_resourceUnavailable_chosen != RRJ_RESOURCE_UNAVAILABLE)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (invalidAlias_chosen != RRJ_INVALID_ALIAS)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if (RegistrationRejectReason_securityDenial_chosen != RRJ_SECURITY_DENIAL)
#error "Registration reject reason code definitions mismatch!! GO back and FIX IT!!"
#endif
// reason codes for GK initiated URQ
#if(reregistrationRequired_chosen != URQ_REREG_REQUIRED)
#error "UnregRequestReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(ttlExpired_chosen != URQ_TTL_EXPIRED)
#error "UnregRequestReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(UnregRequestReason_securityDenial_chosen != URQ_SECURITY_DENIAL)
#error "UnregRequestReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(UnregRequestReason_undefinedReason_chosen != URQ_UNDEFINED)
#error "UnregRequestReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_calledPartyNotRegistered_chosen != ARJ_CALLEE_NOT_REGISTERED)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_invalidPermission_chosen != ARJ_INVALID_PERMISSION)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_requestDenied_chosen != ARJ_REQUEST_DENIED)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_undefinedReason_chosen != ARJ_UNDEFINED)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_callerNotRegistered_chosen != ARJ_CALLER_NOT_REGISTERED)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_routeCallToGatekeeper_chosen != ARJ_ROUTE_TO_GK)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(invalidEndpointIdentifier_chosen != ARJ_INVALID_ENDPOINT_ID)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_resourceUnavailable_chosen != ARJ_RESOURCE_UNAVAILABLE)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(AdmissionRejectReason_securityDenial_chosen != ARJ_SECURTY_DENIAL)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(qosControlNotSupported_chosen != ARJ_QOS_CONTROL_NOT_SUPPORTED)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(incompleteAddress_chosen != ARJ_INCOMPLETE_ADDRESS)
#error "AdmissionRejectReason code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(reregistrationRequired_chosen != URQ_REREG_REQUIRED)
#error "UnregistrationRequest code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(ttlExpired_chosen != URQ_TTL_EXPIRED)
#error "UnregistrationRequest code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(UnregRequestReason_securityDenial_chosen != URQ_SECURITY_DENIAL)
#error "UnregistrationRequest code definitions mismatch!! GO back and FIX IT!!"
#endif
#if(UnregRequestReason_undefinedReason_chosen != URQ_UNDEFINED)
#error "UnregistrationRequest code definitions mismatch!! GO back and FIX IT!!"
#endif
#else // GATEKEEPER
static char ch; // Kludge around warning C4206: nonstandard extension used : translation unit is empty
#endif // GATEKEEPER
|