/**************************************************************************** * * $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.1.6 $ * $Date: 21 Aug 1997 16:56:32 $ * $Author: Helgebal $ * * 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 #pragma warning ( disable : 4115 4201 4214 4514) #include #include #include #include #include "incommon.h" #include "ccerror.h" #include "isrg.h" #include "gkiexp.h" #include "callman2.h" #ifdef FORCE_SERIALIZE_CALL_CONTROL #include "cclock.h" #endif // FORCE_SERIALIZE_CALL_CONTROL #pragma warning ( default : 4115 4201 4214) #if defined(DBG) void GKDbgPrint(DWORD dwLevel, #ifdef UNICODE_TRACE LPTSTR pszFormat, #else LPSTR pszFormat, #endif ...); #define GKDBG(_x_) GKDbgPrint _x_ #else #define GKDBG(_x_) #endif extern HINSTANCE ghCallControlInstance; #define Malloc(size) GlobalAlloc(GMEM_FIXED, size) #define ReAlloc(p, size) GlobalReAlloc(p, GMEM_FIXED, size) #define Free(p) GlobalFree(p) #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 DEFAULT_LISTEN_HANDLE 0xFFFFFFFF #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, 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, 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_CleanupRequest)(void); HRESULT Q931CopyAliasNames(PCC_ALIASNAMES *ppTarget, PCC_ALIASNAMES pSource); HRESULT Q931FreeAliasNames(PCC_ALIASNAMES pSource); #define CopyAliasNames Q931CopyAliasNames #define FreeAliasNames Q931FreeAliasNames typedef struct _LISTEN { struct _LISTEN * pNext; PCC_ALIASNAMES pAliasNames; DWORD 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; 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; HRESULT ValidateCall(DWORD hCall); HRESULT LastGkiError = CC_GKI_STATE; // // Forward declarations // LONG APIENTRY GkiWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam); // // Helper subroutines // #ifdef DBG 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 // DBG HRESULT MapRegistrationRejectReason(register UINT uReason) { 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; } // MapRegistrationRejectReason() HRESULT MapAdmissionRejectReason(register UINT uReason) { register HRESULT lReason; // TBD - Map reason code into CC_xxx HRESULT switch (uReason) { case 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 callerNotRegistered_chosen: lReason = CC_GATEKEEPER_REFUSED; break; case 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 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) { if (pListenList && pListenList->hListen == DEFAULT_LISTEN_HANDLE) { PLISTEN pDefaultListen = pListenList; pListenList = pListenList->pNext; Free(pDefaultListen); } pListen->pNext = pListenList; return pListenList = pListen; } // ListenEnqueue() /* * NOTES * GkiLock must be locked before calling this routine! */ static PLISTEN ListenDequeue(register DWORD 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 = Malloc((uPrefixLength + uDataLength) * sizeof(pAliasItem->pData[0])); if (pAlias->value.u.h323_ID.value == NULL) { GKDBG((1, "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: GKDBG((1, "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; GKDBG((1, "GkiAllocCall: uGkiCalls = %d", uGkiCalls)); } // GkiAllocCall() /* * NOTES * Must have Call locked before calling! */ static HRESULT GkiCancelCall(PGKICALL pGkiCall, void *pConference) { DWORD hCall; ASSERT(pGkiCall != NULL); pConference = pConference; // Disable compiler warning hCall = pGkiCall->hCall; GKDBG((1, 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: GKDBG((1, "GkiCancelCall: Invalid call state %d", pGkiCall->uGkiCallState)); } // switch if (ValidateCall(hCall) == NOERROR && pGkiCall->uGkiCallState != GCS_START) { GkiFreeCall(pGkiCall); } GKDBG((1, 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 GKDBG((1, 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 GKDBG((1, 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); GKDBG((1, 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: GKDBG((1, "GatekeeperNotFound: Invalid call state %d", pGkiCall->uGkiCallState)); } // switch GKDBG((1, CallStateName("GatekeeperNotFound -> Call State = %s", pGkiCall->uGkiCallState), 0)); return NOERROR; } // GatekeeperNotFound() /* * NOTES * GkiLock must be locked before calling this routine! */ static 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()); GKDBG((1, "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()); GKDBG((1, "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; 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; } pTransportAddrs = Malloc(uListens * sizeof(*pTransportAddrs)); if (pTransportAddrs == NULL) { GKDBG((1, "GkiRegister: Could not allocate %d Transport Addresses", uListens)); return CC_NO_MEMORY; } if (uAliasNames) { pAliasAddrs = Malloc(uAliasNames * sizeof(*pAliasAddrs)); if (pAliasAddrs == NULL) { Free(pTransportAddrs); GKDBG((1, "GkiRegister: Could not allocate %d Alias Addresses", uAliasNames)); return CC_NO_MEMORY; } } else { pAliasAddrs = NULL; } pListen = pListenList; uListens = 0; uAliasNames = 0; 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 // TBD - throw out duplicates if (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: Free(pAliasAddrs); Free(pTransportAddrs); GKDBG((1, "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 = TRUE; uGkiState = STATE_REGISTERING; GKDBG((1, "GKI_RegistrationRequest called...", 0)); status = pGKI_RegistrationRequest(GKI_VERSION, // lVersion pTransportAddrs, // pCallSignalAddr &TerminalType, // pTerminalType pAliasAddrs, // pRgstrtnRgst_trmnlAls hwndGki, // hWnd GKIMAN_BASE, // wBaseMessage ipAddress_chosen); // usRegistrationTransport if (status == NOERROR) { GKDBG((1, GkiErrorName("GKI_RegistrationRequest returned %s", status), 0)); } else { GKDBG((1, GkiErrorName("GKI_RegistrationRequest returned %s", status), 0)); uGkiState = STATE_WINDOW_CREATED; } if (pAliasAddrs) Free(pAliasAddrs); if (pTransportAddrs) Free(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; GKDBG((1, "GKI_UnregistrationRequest called...", 0)); status = pGKI_UnregistrationRequest(); if (status == NOERROR) { GKDBG((1, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0)); } else { GKDBG((1, 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: GKDBG((1, "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(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; GKDBG((1, "GKI_UnregistrationRequest called...", 0)); status = pGKI_UnregistrationRequest(); if (status == NOERROR) { GKDBG((1, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0)); } else { GKDBG((1, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0)); uGkiState = STATE_WINDOW_CREATED; } } break; case STATE_WINDOW_CREATED: case STATE_CLASS_REGISTERED: case STATE_START: GKDBG((1, StateName("GkiUnregister: Already in uninitialized state %s", uGkiState), 0)); status = LastGkiError; break; default: GKDBG((1, "GkiUnregister: Invalid state %d", uGkiState)); status = LastGkiError; } // switch return status; } // GkiUnregister() void DeInitGkiManager(void) { register PLISTEN pListen; 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); } Free(pListen); } pGKI_RegistrationRequest = NULL; pGKI_UnregistrationRequest = NULL; pGKI_LocationRequest = NULL; pGKI_AdmissionRequest = NULL; pGKI_BandwidthRequest = NULL; pGKI_DisengageRequest = NULL; if (hGkiDll) { if (pGKI_CleanupRequest) pGKI_CleanupRequest(); #if defined(REMOVE_FROM_TSP) FreeLibrary(hGkiDll); #endif // REMOVE_FROM_TSP } pGKI_CleanupRequest = NULL; LeaveCriticalSection(&GkiLock); DeleteCriticalSection(&GkiLock); DestroyWindow(hwndGki); UnregisterClass(szClassName, 0); } // DeInitGkiManager() HRESULT InitGkiManager(void) { InitializeCriticalSection(&GkiLock); #if defined(REMOVE_FROM_TSP) hGkiDll = LoadLibrary("GKI.DLL"); if (hGkiDll == NULL) { DeInitGkiManager(); return CC_GKI_LOAD; } pGKI_RegistrationRequest = (PGKI_RegistrationRequest) GetProcAddress(hGkiDll, "GKI_RegistrationRequest"); pGKI_UnregistrationRequest = (PGKI_UnregistrationRequest)GetProcAddress(hGkiDll, "GKI_UnregistrationRequest"); pGKI_LocationRequest = (PGKI_LocationRequest) GetProcAddress(hGkiDll, "GKI_LocationRequest"); pGKI_AdmissionRequest = (PGKI_AdmissionRequest) GetProcAddress(hGkiDll, "GKI_AdmissionRequest"); pGKI_BandwidthRequest = (PGKI_BandwidthRequest) GetProcAddress(hGkiDll, "GKI_BandwidthRequest"); pGKI_DisengageRequest = (PGKI_DisengageRequest) GetProcAddress(hGkiDll, "GKI_DisengageRequest"); pGKI_CleanupRequest = (PGKI_CleanupRequest) GetProcAddress(hGkiDll, "GKI_CleanupRequest"); if (pGKI_RegistrationRequest == NULL || pGKI_UnregistrationRequest == NULL || pGKI_LocationRequest == NULL || pGKI_AdmissionRequest == NULL || pGKI_BandwidthRequest == NULL || pGKI_DisengageRequest == NULL || pGKI_CleanupRequest == NULL) { DeInitGkiManager(); return CC_GKI_LOAD; } #else // REMOVE_FROM_TSP pGKI_RegistrationRequest = GKI_RegistrationRequest; pGKI_UnregistrationRequest = GKI_UnregistrationRequest; pGKI_LocationRequest = GKI_LocationRequest; pGKI_AdmissionRequest = GKI_AdmissionRequest; pGKI_BandwidthRequest = GKI_BandwidthRequest; pGKI_DisengageRequest = GKI_DisengageRequest; pGKI_CleanupRequest = GKI_CleanupRequest; #endif // REMOVE_FROM_TSP return NOERROR; } // InitGkiManager() // // Entry Points // HRESULT GkiFreeCall(PGKICALL pGkiCall) { HRESULT status = NOERROR; ASSERT(pGkiCall != NULL); ASSERT(pGkiCall->uGkiCallState != GCS_START); pGkiCall->hGkiCall = 0; while (pGkiCall->pBwReqHead) { Free(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; GKDBG((1, "GkiFreeCall: uGkiCalls = %d", uGkiCalls)); break; default: GKDBG((1, "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 if (pListenList && pListenList->hListen == DEFAULT_LISTEN_HANDLE) { GkiCloseListen(DEFAULT_LISTEN_HANDLE); } } return status; } // GkiFreeCall() HRESULT GkiCloseListen (DWORD hListen) { register PLISTEN pListen; register HRESULT status; GKDBG((1, 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); } Free(pListen); if (pListenList) { status = GkiRegister(); } else { status = GkiUnregister(); } } LeaveCriticalSection(&GkiLock); GKDBG((1, StateName("GkiCloseListen -> State = %s", uGkiState), 0)); return status; } // GkiCloseListen() HRESULT GkiOpenListen (DWORD hListen, PCC_ALIASNAMES pAliasNames, DWORD dwAddr, WORD wPort) { register PLISTEN pListen; register HRESULT status = NOERROR; GKDBG((1, StateName("GkiOpenListen <- State = %s", uGkiState), 0)); EnterCriticalSection(&GkiLock); // Check for invalid IP address if (dwAddr == INADDR_ANY || dwAddr == INADDR_NONE) { dwAddr = GetIpAddress(); if (dwAddr == INADDR_ANY) return CC_GKI_IP_ADDRESS; } // Check for invalid alias list if (pAliasNames) { PCC_ALIASITEM pAliasItem; unsigned int uIndex; if (pAliasNames->wCount == 0) { GKDBG((1, "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 GKDBG((1, "GkiOpenListen: Bad alias item (wDataLength = %d)", pAliasItem->wDataLength)); return CC_BAD_PARAM; } } } pListen = (PLISTEN)Malloc(sizeof(*pListen)); if (pListen) { if (pAliasNames) { status = CopyAliasNames(&pListen->pAliasNames, pAliasNames); if (status != NOERROR) { GKDBG((1, "GkiOpenListen: CopyAliasNames returned 0x%x", status)); LeaveCriticalSection(&GkiLock); return status; } } else { pListen->pAliasNames = NULL; } pListen->hListen = hListen; pListen->dwAddr = ntohl(dwAddr); pListen->wPort = wPort; ListenEnqueue(pListen); status = GkiRegister(); } // if else { GKDBG((1, "GkiOpenListen: Could not allocate listen structure", 0)); status = CC_NO_MEMORY; } // else LeaveCriticalSection(&GkiLock); GKDBG((1, StateName("GkiOpenListen -> State = %s", uGkiState), 0)); return status; } // GkiOpenListen() /* * NOTES * Must have Call locked before calling! */ HRESULT GkiCloseCall(PGKICALL pGkiCall) { HRESULT status = NOERROR; ASSERT(pGkiCall != NULL); GKDBG((1, CallStateName("GkiCloseCall <- Call State = %s", pGkiCall->uGkiCallState), 0)); while (pGkiCall->pBwReqHead) { Free(BwReqDequeue(pGkiCall)); } if (pGkiCall->uGkiCallState == GCS_START) { GKDBG((1, 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: GKDBG((1, CallStateName("GkiCloseCall: Call already in closing state %s", pGkiCall->uGkiCallState), 0)); status = CC_GKI_CALL_STATE; break; case GCS_ADMITTED: pGkiCall->uGkiCallState = GCS_DISENGAGING; GKDBG((1, "GKI_DisengageRequest called...", 0)); ++uPendingDisengages; status = pGKI_DisengageRequest(pGkiCall->hGkiCall); if (status == NOERROR) { GKDBG((1, GkiErrorName("GKI_DisengageRequest returned %s", status), 0)); } else { --uPendingDisengages; GKDBG((1, GkiErrorName("GKI_DisengageRequest returned %s", status), 0)); GkiFreeCall(pGkiCall); } break; case GCS_CHANGING: pGkiCall->uGkiCallState = GCS_CHANGING_CLOSE_PENDING; break; default: GKDBG((1, CallStateName("GkiCloseCall: Call in invalid state %s", pGkiCall->uGkiCallState), 0)); status = CC_GKI_CALL_STATE; } // switch } // switch } // else GKDBG((1, 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; DWORD 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)); } } Free(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; DWORD 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); } Free(pBwReq); if (ValidateCall(hCall) != NOERROR) { return status; } } if (pGkiCall->pBwReqHead != NULL) { pGkiCall->uGkiCallState = GCS_CHANGING; GKDBG((1, "GKI_BandwidthRequest called...", 0); status = pGKI_BandwidthRequest(pGkiCall->hGkiCall, pGkiCall->usCallTypeChoice, pGkiCall->uBandwidthUsed + pGkiCall->pBwReqHead->uChannelBandwidth)); if (status == NOERROR) { GKDBG((1, GkiErrorName("GKI_BandwidthRequest returned %s", status), 0)); } else { GKDBG((1, 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) Free(pAlias->value.u.h323_ID.value); pAlias = pAlias->next; } Free(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 ??? */ HRESULT GkiOpenCall (PGKICALL pGkiCall, void *pConference) { HRESULT status = NOERROR; DWORD hCall; TransportAddress SrcCallSignalAddress; TransportAddress * pSrcCallSignalAddress; TransportAddress DestCallSignalAddress; TransportAddress * pDestCallSignalAddress; SeqAliasAddr * pAliasAddrs; SeqAliasAddr * pExtraAliasAddrs; SeqAliasAddr * pAlias; PCC_ALIASITEM pAliasItem; unsigned uCount; unsigned uIndex; ConferenceIdentifier ConferenceId; ASSERT(pGkiCall != NULL); ASSERT(pConference != NULL); GKDBG((1, 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); GKDBG((1, "GkiOpenCall -> Invalid CallType %d", pGkiCall->CallType)); return CC_BAD_PARAM; } // switch pSrcCallSignalAddress = NULL; pDestCallSignalAddress = NULL; pAliasAddrs = NULL; pExtraAliasAddrs = NULL; if (pGkiCall->dwSrcCallSignalIpAddress != 0 && pGkiCall->wSrcCallSignalPort != 0) { SrcCallSignalAddress.choice = ipAddress_chosen; SrcCallSignalAddress.u.ipAddress.ip.length = 4; *((DWORD *)SrcCallSignalAddress.u.ipAddress.ip.value) = pGkiCall->dwSrcCallSignalIpAddress; SrcCallSignalAddress.u.ipAddress.port = pGkiCall->wSrcCallSignalPort; pSrcCallSignalAddress = &SrcCallSignalAddress; } 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) { // pDestCallSignalAddress = NULL; uCount = pGkiCall->pCalleeAliasNames->wCount; pAliasAddrs = Malloc(uCount * sizeof(*pAliasAddrs)); if (pAliasAddrs == NULL) { LeaveCriticalSection(&GkiLock); GKDBG((1, "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); GKDBG((1, "GkiOpenCall: CopyAliasItem returned %d", status)); FreeAliasList(pAliasAddrs); return status; } pAlias->next = pAlias + 1; ++pAlias; ++pAliasItem; } // for --pAlias; pAlias->next = NULL; } if (pGkiCall->pCalleeExtraAliasNames) { uCount = pGkiCall->pCalleeExtraAliasNames->wCount; pExtraAliasAddrs = Malloc(uCount * sizeof(*pExtraAliasAddrs)); if (pExtraAliasAddrs == NULL) { LeaveCriticalSection(&GkiLock); GKDBG((1, "GkiOpenCall: Could not allocate %d Alias Addresses", uCount)); if (pAliasAddrs) FreeAliasList(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); GKDBG((1, "GkiOpenCall: CopyAliasItem returned %d", status)); if (pAliasAddrs) FreeAliasList(pAliasAddrs); FreeAliasList(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; GKDBG((1, "GKI_AdmissionRequest called...", 0); status = pGKI_AdmissionRequest(pGkiCall->usCallTypeChoice, // usCallTypeChoice. pAliasAddrs, // pDestinationInfo pGkiCall->bAnswerCall ? pSrcCallSignalAddress : pDestCallSignalAddress, pExtraAliasAddrs, // pDestExtraCallInfo, pGkiCall->uBandwidthRequested, // bandWidth, &ConferenceId, // pConferenceID, pGkiCall->bActiveMC, // activeMC, pGkiCall->bAnswerCall, // answerCall, ipAddress_chosen)); // usCallTransport if (status == NOERROR) { GKDBG((1, GkiErrorName("GKI_AdmissionRequest returned %s", status), 0)); } else { GKDBG((1, 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); if (pExtraAliasAddrs) FreeAliasList(pExtraAliasAddrs); break; case STATE_START: case STATE_CLASS_REGISTERED: case STATE_WINDOW_CREATED: pGkiCall->uGkiCallState = GCS_WAITING; status = GkiOpenListen(DEFAULT_LISTEN_HANDLE, NULL, 0, 1720); break; default: GKDBG((1, StateName("GkiOpenCall: Invalid state %s", uGkiState), 0)); status = LastGkiError; } // switch LeaveCriticalSection(&GkiLock); GKDBG((1, CallStateName("GkiOpenCall -> Call State = %s", pGkiCall->uGkiCallState), 0)); return status; } // GkiOpenCall() /* * NOTES * Must have Call locked before calling! */ HRESULT GkiOpenChannel(PGKICALL pGkiCall, unsigned uChannelBandwidth, DWORD hChannel, CHANNELTYPE Type) { HRESULT status = NOERROR; PBWREQ pBwReq; ASSERT(pGkiCall != NULL); GKDBG((1, CallStateName("GkiOpenChannel <- Call State = %s", pGkiCall->uGkiCallState), 0)); pBwReq = (PBWREQ)Malloc(sizeof(*pBwReq)); if (pBwReq == NULL) { GKDBG((1, "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: GKDBG((1, "GkiOpenChannel: Invalid call state %d", pGkiCall->uGkiCallState)); status = CC_GKI_CALL_STATE; } // switch GKDBG((1, CallStateName("GkiOpenChannel -> Call State = %s", pGkiCall->uGkiCallState), 0)); return status; } // GkiOpenChannel() /* * NOTES * Must have Call locked before calling! */ HRESULT GkiCloseChannel(PGKICALL pGkiCall, unsigned uChannelBandwidth, DWORD hChannel) { PBWREQ pBwReq; PBWREQ pBwReq1; ASSERT(pGkiCall != NULL); GKDBG((1, 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) { Free(BwReqDequeue(pGkiCall)); GKDBG((1, 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; Free(pBwReq1); GKDBG((1, CallStateName("GkiCloseChannel -> Call State = %s", pGkiCall->uGkiCallState), 0)); return NOERROR; } } } pGkiCall->uBandwidthUsed -= (uChannelBandwidth / 100); GKDBG((1, 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: GKDBG((1, "GkiWndProc: dummy GKI_REG_REJECT", 0)); PostMessage(hWnd, GKIMAN_BASE + GKI_REG_REJECT, 0, 0); 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); GKDBG((1, "GKI_UnregistrationRequest called...", 0)); status = pGKI_UnregistrationRequest(); if (status == NOERROR) { GKDBG((1, GkiErrorName("GKI_UnregistrationRequest returned %s", status), 0)); } else { GKDBG((1, 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: GKDBG((1, "GkiWndProc: dummy GKI_UNREG_CONFIRM", 0)); PostMessage(hWnd, GKIMAN_BASE + GKI_UNREG_CONFIRM, 0, 0); break; default: GKDBG((1, "GkiWndProc: Bad uGkiState %d", uGkiState)); } // switch } // GkiNoResponse() LONG APIENTRY GkiWndProc( HWND hWnd, /* window handle */ UINT message, /* type of message */ UINT wParam, /* additional information */ LONG lParam) /* additional information */ { CallReturnInfo * pCallReturnInfo; PGKICALL pGkiCall; void * pConference; DWORD hCall; DWORD hConference; HRESULT status; if (message < GKIMAN_BASE) { return DefWindowProc(hWnd, message, wParam, lParam); } EnterCallControlTop(); GKDBG((1, StateName("GkiWndProc <- State = %s", uGkiState), 0)); switch (message) { case GKIMAN_BASE + GKI_REG_CONFIRM: GKDBG((1, "GkiWndProc: GKI_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: GKDBG((1, StateName("GkiWndProc: GKI_REG_CONFIRM in state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_REG_DISCOVERY: GKDBG((1, "GkiWndProc: GKI_REG_DISCOVERY", 0)); ASSERT(uGkiState == STATE_REGISTERING || uGkiState == STATE_REGISTERING_REREG || uGkiState == STATE_REGISTERING_UNREG); break; case GKIMAN_BASE + GKI_REG_REJECT: GKDBG((1, "GkiWndProc: GKI_REG_REJECT Reason = %d", wParam)); switch (uGkiState) { case STATE_REGISTERING: ApplyToAllCalls(GkiCancelCall); EnterCriticalSection(&GkiLock); while (pListenList) { register PLISTEN pListen = pListenList; pListenList = pListen->pNext; LeaveCriticalSection(&GkiLock); ListenReject(pListen->hListen, MapRegistrationRejectReason(wParam)); if (pListen->pAliasNames) { FreeAliasNames(pListen->pAliasNames); } Free(pListen); EnterCriticalSection(&GkiLock); } LeaveCriticalSection(&GkiLock); uGkiState = STATE_WINDOW_CREATED; break; case STATE_REGISTERING_REREG: uGkiState = STATE_WINDOW_CREATED; GkiRegister(); break; case STATE_REGISTERING_UNREG: uGkiState = STATE_WINDOW_CREATED; GkiUnregister(); break; default: GKDBG((1, StateName("GkiWndProc: GKI_REG_REJECT in state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_REG_BYPASS: GKDBG((1, "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: GKDBG((1, StateName("GkiWndProc: GKI_REG_BYPASS in state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_UNREG_CONFIRM: GKDBG((1, "GkiWndProc: GKI_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: GKDBG((1, 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: GKDBG((1, "GkiWndProc: GKI_UNREG_REJECT Reason = %d", wParam)); switch (uGkiState) { case STATE_UNREGISTERING: uGkiState = STATE_WINDOW_CREATED; GkiUnregister(); break; case STATE_UNREGISTERING_REREG: uGkiState = STATE_WINDOW_CREATED; GkiRegister(); break; default: GKDBG((1, StateName("GkiWndProc: GKI_UNREG_REJECT in state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_ADM_CONFIRM: GKDBG((1, "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) { GKDBG((1, 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->dwIpAddress = pGkiCall->dwIpAddress; 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: GKDBG((1, CallStateName("GkiWndProc: GKI_ADM_CONFIRM in call state %s", pGkiCall->uGkiCallState), 0)); } // switch UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if else { GKDBG((1, "GkiWndProc: GKI_ADM_CONFIRM handle not found", 0)); } ApplyToAllCalls(CheckPendingOpen); break; case STATE_ADMITTING_UNREG: uGkiState = STATE_REGISTERED; GkiUnregister(); break; default: GKDBG((1, StateName("GkiWndProc: GKI_ADM_CONFIRM in state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_ADM_REJECT: GKDBG((1, "GkiWndProc: GKI_ADM_REJECT Reason = %d", 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 calledPartyNotRegistered_chosen: if (pGkiCall->bAnswerCall) { // The gateway has gone away and come back without our notice! GkiCancelAdmitting(pGkiCall, pConference); uGkiState = STATE_REGISTERED; GkiRegister(); GKDBG((1, StateName("GkiWndProc -> State = %s", uGkiState), 0)); LeaveCallControlTop(0); } break; case callerNotRegistered_chosen: if (pGkiCall->bAnswerCall == FALSE) { // The gateway has gone away and come back without our notice! GkiCancelAdmitting(pGkiCall, pConference); uGkiState = STATE_REGISTERED; GkiRegister(); GKDBG((1, StateName("GkiWndProc -> State = %s", uGkiState), 0)); LeaveCallControlTop(0); } } // switch GkiFreeCall(pGkiCall); if (pGkiCall->bAnswerCall) AcceptCallReject(pGkiCall->pCall, pConference, MapAdmissionRejectReason(wParam)); else PlaceCallReject (pGkiCall->pCall, pConference, MapAdmissionRejectReason(wParam)); UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if else { GKDBG((1, "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(wParam)); } else { PlaceCallReject (pGkiCall->pCall, pConference, MapAdmissionRejectReason(wParam)); } UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if else { GKDBG((1, "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(wParam)); } else { PlaceCallReject (pGkiCall->pCall, pConference, MapAdmissionRejectReason(wParam)); } UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if else { GKDBG((1, "GkiWndProc: GKI_ADM_REJECT handle not found", 0)); } uGkiState = STATE_REGISTERED; GkiUnregister(); break; default: GKDBG((1, StateName("GkiWndProc: GKI_ADM_REJECT in state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_BW_CONFIRM: GKDBG((1, "GkiWndProc: GKI_BW_CONFIRM", 0)); switch (uGkiState) { case STATE_REGISTERED: pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(pCallReturnInfo->hCall, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { GKDBG((1, 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: GKDBG((1, CallStateName("GkiWndProc: GKI_BW_CONFIRM in call state %s", pGkiCall->uGkiCallState), 0)); } // switch UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if else { GKDBG((1, "GkiWndProc: GKI_BW_CONFIRM handle not found", 0)); } // else break; default: GKDBG((1, StateName("GkiWndProc: GKI_BW_CONFIRM in GKI state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_BW_REJECT: GKDBG((1, "GkiWndProc: GKI_BW_REJECT Reason = %d", wParam)); switch (uGkiState) { case STATE_REGISTERED: pCallReturnInfo = (CallReturnInfo *) lParam; if (LockGkiCallAndConference(pCallReturnInfo->hCall, &pGkiCall, &pConference, &hCall, &hConference) == NOERROR) { GKDBG((1, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0)); pGkiCall->uBandwidthAllocated = pCallReturnInfo->bandWidth; switch (pGkiCall->uGkiCallState) { case GCS_CHANGING: pGkiCall->uGkiCallState = GCS_ADMITTED; BandwidthRejected(pGkiCall, wParam); if (ValidateCall(hCall) == NOERROR) { CheckPendingBandwidth(pGkiCall); } break; case GCS_CHANGING_CLOSE_PENDING: pGkiCall->uGkiCallState = GCS_ADMITTED; GkiCloseCall(pGkiCall); break; default: GKDBG((1, CallStateName("GkiWndProc: GKI_BW_REJECT in state %s", pGkiCall->uGkiCallState), 0)); } // switch UnlockGkiCallAndConference(pGkiCall, pConference, hCall, hConference); } // if else { GKDBG((1, "GkiWndProc: GKI_BW_REJECT handle not found", 0)); } break; default: GKDBG((1, StateName("GkiWndProc: GKI_BW_REJECT in state %s", uGkiState), 0)); } // switch break; case GKIMAN_BASE + GKI_DISENG_CONFIRM: GKDBG((1, "GkiWndProc: GKI_DISENG_CONFIRM", 0)); if (LockGkiCall((HANDLE)lParam, &pGkiCall) == NOERROR) { GKDBG((1, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0)); switch (pGkiCall->uGkiCallState) { case GCS_DISENGAGING: --uPendingDisengages; break; default: GKDBG((1, 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 (pListenList && pListenList->hListen == DEFAULT_LISTEN_HANDLE) { GkiCloseListen(DEFAULT_LISTEN_HANDLE); } } // if } // else if else { GKDBG((1, "GkiWndProc: GKI_DISENG_CONFIRM handle not found", 0)); } break; case GKIMAN_BASE + GKI_DISENG_REJECT: GKDBG((1, "GkiWndProc: GKI_DISENG_REJECT Reason = %d", wParam)); if (LockGkiCall((HANDLE)lParam, &pGkiCall) == NOERROR) { GKDBG((1, CallStateName("GkiWndProc: Call State = %s", pGkiCall->uGkiCallState), 0)); switch (pGkiCall->uGkiCallState) { case GCS_DISENGAGING: // Pretend we received a Disengage Confirm --uPendingDisengages; break; default: GKDBG((1, 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 (pListenList && pListenList->hListen == DEFAULT_LISTEN_HANDLE) { GkiCloseListen(DEFAULT_LISTEN_HANDLE); } } // if } // else if else { GKDBG((1, "GkiWndProc: GKI_DISENG_REJECT handle not found", 0)); } break; case GKIMAN_BASE + GKI_LOCATION_CONFIRM: GKDBG((1, "GkiWndProc: GKI_LOCATION_CONFIRM", 0)); break; case GKIMAN_BASE + GKI_LOCATION_REJECT: GKDBG((1, "GkiWndProc: GKI_LOCATION_REJECT Reason = %d", wParam)); break; case GKIMAN_BASE + GKI_ERROR: GKDBG((1, GkiErrorName("GkiWndProc: GKI_ERROR %s %%d", lParam), wParam)); switch (lParam) { case GKI_NO_RESPONSE: LastGkiError = 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 = lParam; GkiUnregister(); } // switch break; default: GKDBG((1, "Unknown message %d", message)); } // switch GKDBG((1, StateName("GkiWndProc -> State = %s", uGkiState), 0)); LeaveCallControlTop(0); } // GkiWndProc() #if defined(DBG) DWORD g_dwH225DbgLevel = 0; BOOL g_fInitialized = FALSE; void GKDbgInit() { #define H323_REGKEY_ROOT \ TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\H323TSP") #define H323_REGVAL_DEBUGLEVEL \ TEXT("DebugLevel") #define H323_REGVAL_H225DEBUGLEVEL \ TEXT("H225DebugLevel") HKEY hKey; LONG lStatus; DWORD dwValue; DWORD dwValueSize; DWORD dwValueType; LPSTR pszValue; LPSTR pszKey = H323_REGKEY_ROOT; // only call this once g_fInitialized = TRUE; // open registry subkey lStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE, pszKey, 0, KEY_READ, &hKey ); // validate return code if (lStatus != ERROR_SUCCESS) { return; // bail... } // initialize values dwValueType = REG_DWORD; dwValueSize = sizeof(DWORD); // retrieve ras debug level pszValue = H323_REGVAL_H225DEBUGLEVEL; // query for registry value lStatus = RegQueryValueEx( hKey, pszValue, NULL, &dwValueType, (LPBYTE)&dwValue, &dwValueSize ); // validate return code if (lStatus != ERROR_SUCCESS) { // initialize values dwValueType = REG_DWORD; dwValueSize = sizeof(DWORD); // retrieve tsp debug level pszValue = H323_REGVAL_DEBUGLEVEL; // query for registry value lStatus = RegQueryValueEx( hKey, pszValue, NULL, &dwValueType, (LPBYTE)&dwValue, &dwValueSize ); } // validate return code if (lStatus == ERROR_SUCCESS) { // update debug level g_dwH225DbgLevel = dwValue; } // close key RegCloseKey(hKey); } void GKDbgPrint(DWORD dwLevel, #ifdef UNICODE_TRACE LPTSTR pszFormat, #else LPSTR pszFormat, #endif ...) { #define DEBUG_FORMAT_HEADER "H225 " #define DEBUG_FORMAT_TIMESTAMP "[%02u:%02u:%02u.%03u" #define DEBUG_FORMAT_THREADID ",tid=%x] " #define MAXDBG_STRLEN 512 va_list Args; SYSTEMTIME SystemTime; char szDebugMessage[MAXDBG_STRLEN+1]; int nLengthRemaining; int nLength = 0; // make sure initialized if (g_fInitialized == FALSE) { GKDbgInit(); } // validate debug log level if (dwLevel > g_dwH225DbgLevel) { return; // bail... } // retrieve local time GetLocalTime(&SystemTime); // add component header to the debug message nLength += sprintf(&szDebugMessage[nLength], DEBUG_FORMAT_HEADER ); // add timestamp to the debug message nLength += sprintf(&szDebugMessage[nLength], DEBUG_FORMAT_TIMESTAMP, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds ); // add thread id to the debug message nLength += sprintf(&szDebugMessage[nLength], DEBUG_FORMAT_THREADID, GetCurrentThreadId() ); // point at first argument va_start(Args, pszFormat); // determine number of bytes left in buffer nLengthRemaining = sizeof(szDebugMessage) - nLength; // add user specified debug message _vsnprintf(&szDebugMessage[nLength], nLengthRemaining, pszFormat, Args ); // release pointer va_end(Args); // output message to specified sink OutputDebugString(szDebugMessage); OutputDebugString("\n"); } #endif #else // GATEKEEPER static char ch; // Kludge around warning C4206: nonstandard extension used : translation unit is empty #endif // GATEKEEPER