aboutsummaryrefslogtreecommitdiffstats
path: root/addons/ooh323c/src/ooGkClient.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2009-06-30 16:40:38 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2009-06-30 16:40:38 +0000
commite9d15cbea7a98184521c851500176da7aa424012 (patch)
treed3d6aa7ea86d11ecaa6e88efbc46a5dde1c63ea5 /addons/ooh323c/src/ooGkClient.c
parentb85bdd32a783a8f07004d41db8a696645685a331 (diff)
Move Asterisk-addons modules into the main Asterisk source tree.
Someone asked yesterday, "is there a good reason why we can't just put these modules in Asterisk?". After a brief discussion, as long as the modules are clearly set aside in their own directory and not enabled by default, it is perfectly fine. For more information about why a module goes in addons, see README-addons.txt. chan_ooh323 does not currently compile as it is behind some trunk API updates. However, it will not build by default, so it should be okay for now. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@204413 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'addons/ooh323c/src/ooGkClient.c')
-rw-r--r--addons/ooh323c/src/ooGkClient.c2443
1 files changed, 2443 insertions, 0 deletions
diff --git a/addons/ooh323c/src/ooGkClient.c b/addons/ooh323c/src/ooGkClient.c
new file mode 100644
index 000000000..1a920e3a7
--- /dev/null
+++ b/addons/ooh323c/src/ooGkClient.c
@@ -0,0 +1,2443 @@
+/*
+ * Copyright (C) 2005 by Page Iberica, S.A.
+ * Copyright (C) 2005 by Objective Systems, Inc.
+ *
+ * This software is furnished under an open source license and may be
+ * used and copied only in accordance with the terms of this license.
+ * The text of the license may generally be found in the root
+ * directory of this installation in the COPYING file. It
+ * can also be viewed online at the following URL:
+ *
+ * http://www.obj-sys.com/open/license.html
+ *
+ * Any redistributions of this file including modified versions must
+ * maintain this copyright notice.
+ *
+ *****************************************************************************/
+
+/**
+ * @file ooGkClient.c
+ * This file contains functions to support RAS protocol.
+ *
+ */
+#include "ooGkClient.h"
+#include "ootypes.h"
+#include "ootrace.h"
+#include "ooports.h"
+#include "ooasn1.h"
+#include "oochannels.h"
+#include "printHandler.h"
+#include "ooCalls.h"
+#include "H323-MESSAGES.h"
+#include "ooDateTime.h"
+#include "ooq931.h"
+#include "ooh323.h"
+#include "ooh323ep.h"
+#include "ooTimer.h"
+#include "ooSocket.h"
+#include "ooUtils.h"
+
+/** Global endpoint structure */
+extern OOH323EndPoint gH323ep;
+
+static ASN1OBJID gProtocolID = {
+ 6, { 0, 0, 8, 2250, 0, 4 }
+};
+
+int ooGkClientInit(enum RasGatekeeperMode eGkMode,
+ char *szGkAddr, int iGkPort )
+{
+ ooGkClient *pGkClient=NULL;
+ OOInterface *cur=NULL;
+ pGkClient = (ooGkClient*)
+ memAlloc(&gH323ep.ctxt, sizeof(ooGkClient));
+ if(!pGkClient)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory to Gatekeeper Client.\n");
+ return OO_FAILED;
+ }
+
+ memset(pGkClient, 0, sizeof(ooGkClient));
+ gH323ep.gkClient = pGkClient;
+ initContext(&(pGkClient->ctxt));
+ initContext(&(pGkClient->msgCtxt));
+ pGkClient->rrqRetries = 0;
+ pGkClient->grqRetries = 0;
+
+ strcpy(pGkClient->localRASIP, gH323ep.signallingIP);
+#ifndef _WIN32
+ if(!strcmp(pGkClient->localRASIP, "0.0.0.0") ||
+ !strcmp(pGkClient->localRASIP, "127.0.0.1"))
+ {
+ if(!gH323ep.ifList)
+ {
+ if(ooSocketGetInterfaceList(&gH323ep.ctxt, &gH323ep.ifList)!= ASN_OK)
+ {
+ OOTRACEERR1("Error:Failed to retrieve interface addresses\n");
+ return OO_FAILED;
+ }
+ }
+ for(cur = gH323ep.ifList; cur; cur = cur->next)
+ {
+ if(!strcmp(cur->name, "lo") || !strcmp(cur->addr, "127.0.0.1"))
+ continue;
+ break;
+ }
+ if(cur)
+ {
+ OOTRACEINFO2("Using local RAS Ip address %s\n", cur->addr);
+ strcpy(pGkClient->localRASIP, cur->addr);
+ }
+ else{
+ OOTRACEERR1("Error:Failed to assign a local RAS IP address\n");
+ return OO_FAILED;
+ }
+ }
+#endif
+ if(OO_OK != ooGkClientSetGkMode(pGkClient, eGkMode, szGkAddr, iGkPort))
+ {
+ OOTRACEERR1("Error:Failed to set Gk mode\n");
+ memReset(&gH323ep.ctxt);
+ return OO_FAILED;
+ }
+
+ /* Create default parameter set */
+ pGkClient->grqTimeout = DEFAULT_GRQ_TIMEOUT;
+ pGkClient->rrqTimeout = DEFAULT_RRQ_TIMEOUT;
+ pGkClient->regTimeout = DEFAULT_REG_TTL;
+ pGkClient->arqTimeout = DEFAULT_ARQ_TIMEOUT;
+ pGkClient->drqTimeout = DEFAULT_DRQ_TIMEOUT;
+ dListInit(&pGkClient->callsPendingList);
+ dListInit(&pGkClient->callsAdmittedList);
+ dListInit(&pGkClient->timerList);
+ pGkClient->state = GkClientIdle;
+ return OO_OK;
+}
+
+
+int ooGkClientSetCallbacks
+ (ooGkClient *pGkClient, OOGKCLIENTCALLBACKS callbacks)
+{
+ pGkClient->callbacks.onReceivedRegistrationConfirm =
+ callbacks.onReceivedRegistrationConfirm;
+ pGkClient->callbacks.onReceivedUnregistrationConfirm =
+ callbacks.onReceivedUnregistrationConfirm;
+ pGkClient->callbacks.onReceivedUnregistrationRequest =
+ callbacks.onReceivedUnregistrationRequest;
+ return OO_OK;
+}
+
+int ooGkClientReInit(ooGkClient *pGkClient)
+{
+
+ ooGkClientCloseChannel(pGkClient);
+ pGkClient->gkRasIP[0]='\0';
+ pGkClient->gkCallSignallingIP[0]='\0';
+ pGkClient->gkRasPort = 0;
+ pGkClient->gkCallSignallingPort = 0;
+ pGkClient->rrqRetries = 0;
+ pGkClient->grqRetries = 0;
+ pGkClient->requestSeqNum = 0;
+
+ dListFreeAll(&pGkClient->ctxt, &pGkClient->callsPendingList);
+ dListFreeAll(&pGkClient->ctxt, &pGkClient->callsAdmittedList);
+ dListFreeAll(&pGkClient->ctxt, &pGkClient->timerList);
+ pGkClient->state = GkClientIdle;
+ return OO_OK;
+}
+
+void ooGkClientPrintConfig(ooGkClient *pGkClient)
+{
+ OOTRACEINFO1("Gatekeeper Client Configuration:\n");
+ if(pGkClient->gkMode == RasUseSpecificGatekeeper)
+ {
+ OOTRACEINFO1("\tGatekeeper mode - UseSpecificGatekeeper\n");
+ OOTRACEINFO3("\tGatekeeper To Use - %s:%d\n", pGkClient->gkRasIP,
+ pGkClient->gkRasPort);
+ }
+ else if(pGkClient->gkMode == RasDiscoverGatekeeper) {
+ OOTRACEINFO1("\tGatekeeper mode - UseSpecificGatekeeper\n");
+ }
+ else {
+ OOTRACEERR1("Invalid GatekeeperMode\n");
+ }
+}
+
+int ooGkClientDestroy(void)
+{
+ if(gH323ep.gkClient)
+ {
+ if(gH323ep.gkClient->state == GkClientRegistered)
+ {
+ OOTRACEINFO1("Unregistering from Gatekeeper\n");
+ if(ooGkClientSendURQ(gH323ep.gkClient, NULL)!=OO_OK)
+ OOTRACEERR1("Error:Failed to send URQ to gatekeeper\n");
+ }
+ OOTRACEINFO1("Destroying Gatekeeper Client\n");
+ ooGkClientCloseChannel(gH323ep.gkClient);
+ freeContext(&gH323ep.gkClient->msgCtxt);
+ freeContext(&gH323ep.gkClient->ctxt);
+ memFreePtr(&gH323ep.ctxt, gH323ep.gkClient);
+ gH323ep.gkClient = NULL;
+ }
+ return OO_OK;
+}
+
+int ooGkClientStart(ooGkClient *pGkClient)
+{
+ int iRet=0;
+ iRet = ooGkClientCreateChannel(pGkClient);
+
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error: GkClient Channel Creation failed\n");
+ return OO_FAILED;
+ }
+
+ pGkClient->discoveryComplete = FALSE;
+ iRet = ooGkClientSendGRQ(pGkClient);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send GRQ message\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ return OO_OK;
+}
+
+
+int ooGkClientSetGkMode(ooGkClient *pGkClient, enum RasGatekeeperMode eGkMode,
+ char *szGkAddr, int iGkPort )
+{
+ pGkClient->gkMode = eGkMode;
+ if(eGkMode == RasUseSpecificGatekeeper)
+ {
+ OOTRACEINFO1("Gatekeeper Mode - RasUseSpecificGatekeeper\n");
+ if(szGkAddr)
+ {
+ if(strlen(szGkAddr)>MAX_IP_LEN)
+ {
+ OOTRACEERR2("Error:Invalid IP address specified - %s\n", szGkAddr);
+ return OO_FAILED;
+ }
+ strcpy(pGkClient->gkRasIP, szGkAddr);
+ }
+ if(iGkPort)
+ pGkClient->gkRasPort = iGkPort;
+ else
+ pGkClient->gkRasPort = DEFAULT_GKPORT;
+
+ OOTRACEINFO3("Gatekeeper IP:port set to - %s:%d\n",
+ szGkAddr, pGkClient->gkRasPort);
+ }
+ else if(eGkMode == RasDiscoverGatekeeper) {
+ OOTRACEINFO1("Gatekeeper Mode - RasDiscoverGatekeeper\n");
+ }
+ else if(eGkMode == RasNoGatekeeper) {
+ OOTRACEINFO1("Gatekeeper Mode - RasNoGatekeeper\n");
+ }
+ return OO_OK;
+}
+
+
+/**
+ * Create the RAS channel (socket).
+ *
+ */
+
+int ooGkClientCreateChannel(ooGkClient *pGkClient)
+{
+ int ret=0;
+ OOIPADDR ipaddrs;
+ /* Create socket */
+ if((ret=ooSocketCreateUDP(&pGkClient->rasSocket))!=ASN_OK)
+ {
+ OOTRACEERR1("Failed to create RAS socket\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ if(pGkClient->localRASPort)
+ {
+ ret= ooSocketStrToAddr (pGkClient->localRASIP, &ipaddrs);
+ if( (ret=ooSocketBind( pGkClient->rasSocket, ipaddrs,
+ pGkClient->localRASPort))!=ASN_OK )
+ {
+ OOTRACEERR1("ERROR:Failed to create RAS channel\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ }
+ else {
+ ret = ooBindPort (OOUDP, pGkClient->rasSocket, pGkClient->localRASIP);
+ if(ret == OO_FAILED)
+ {
+ OOTRACEERR1("ERROR: Failed to bind port to RAS socket\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pGkClient->localRASPort = ret;
+ }
+ /* Test Code NOTE- This doesn't work..:(( Have to fix this */
+ /* If multihomed, get ip from socket */
+ if(!strcmp(pGkClient->localRASIP, "0.0.0.0"))
+ {
+ OOTRACEDBGA1("Determining ip address for RAS channel "
+ "multihomed mode. \n");
+ ret = ooSocketGetIpAndPort(pGkClient->rasSocket, pGkClient->localRASIP,
+ 20, &pGkClient->localRASPort);
+ if(ret != ASN_OK)
+ {
+ OOTRACEERR1("Error:Failed to retrieve local ip and port from "
+ "socket for RAS channel(multihomed).\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ OOTRACEDBGA3("Using local ip %s and port %d for RAS channel"
+ "(multihomedMode).\n", pGkClient->localRASIP,
+ pGkClient->localRASPort);
+ }
+ /* End of Test code */
+ OOTRACEINFO1("H323 RAS channel creation - successful\n");
+ return OO_OK;
+}
+
+
+int ooGkClientCloseChannel(ooGkClient *pGkClient)
+{
+ int ret;
+ if(pGkClient->rasSocket != 0)
+ {
+ ret = ooSocketClose(pGkClient->rasSocket);
+ if(ret != ASN_OK)
+ {
+ OOTRACEERR1("Error: failed to close RAS channel\n");
+ pGkClient->rasSocket = 0;
+ return OO_FAILED;
+ }
+ pGkClient->rasSocket = 0;
+ }
+ OOTRACEINFO1("Closed RAS channel\n");
+ return OO_OK;
+}
+
+
+/**
+ * Fill vendor data in RAS message structure.
+ */
+
+void ooGkClientFillVendor
+ (ooGkClient *pGkClient, H225VendorIdentifier *pVendor )
+{
+ pVendor->vendor.t35CountryCode = gH323ep.t35CountryCode;
+ pVendor->vendor.t35Extension = gH323ep.t35Extension;
+ pVendor->vendor.manufacturerCode = gH323ep.manufacturerCode;
+ pVendor->enterpriseNumber.numids=0;
+ if(gH323ep.productID)
+ {
+ pVendor->m.productIdPresent = TRUE;
+ pVendor->productId.numocts = ASN1MIN(strlen(gH323ep.productID),
+ sizeof(pVendor->productId.data));
+ memcpy(pVendor->productId.data, gH323ep.productID,
+ pVendor->productId.numocts);
+ }
+ if(gH323ep.versionID)
+ {
+ pVendor->m.versionIdPresent = 1;
+ pVendor->versionId.numocts = ASN1MIN(strlen(gH323ep.versionID),
+ sizeof(pVendor->versionId.data));
+ memcpy(pVendor->versionId.data, gH323ep.versionID,
+ pVendor->versionId.numocts);
+ }
+}
+
+
+int ooGkClientReceive(ooGkClient *pGkClient)
+{
+ ASN1OCTET recvBuf[1024];
+ int recvLen;
+ char remoteHost[32];
+ int iFromPort=0;
+ OOCTXT *pctxt=NULL;
+ H225RasMessage *pRasMsg=NULL;
+ int iRet=OO_OK;
+
+ pctxt = &pGkClient->msgCtxt;
+
+ recvLen = ooSocketRecvFrom(pGkClient->rasSocket, recvBuf, 1024, remoteHost,
+ 32, &iFromPort);
+ if(recvLen <0)
+ {
+ OOTRACEERR1("Error:Failed to receive RAS message\n");
+ return OO_FAILED;
+ }
+ OOTRACEDBGA1("GkClient Received RAS Message\n");
+
+ /* Verify the gk */
+ if(pGkClient->discoveryComplete)
+ {
+ if((strncmp(pGkClient->gkRasIP, remoteHost,strlen(pGkClient->gkRasIP)))||
+ (pGkClient->gkRasPort!= iFromPort) )
+ {
+ OOTRACEWARN3("WARN:Ignoring message received from unknown gatekeeper "
+ "%s:%d\n", remoteHost, iFromPort);
+ return OO_OK;
+ }
+ }
+
+ if(ASN_OK != setPERBuffer (pctxt, recvBuf, recvLen, TRUE ) )
+ {
+ OOTRACEERR1("Error:Failed to set PER buffer for RAS message decoding\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
+ if(!pRasMsg)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory for RAS message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+#ifndef _COMPACT
+ initializePrintHandler(&printHandler, "Received RAS Message");
+ /* Add event handler to list */
+ setEventHandler (pctxt, &printHandler);
+#endif
+ if(ASN_OK == asn1PD_H225RasMessage(pctxt, pRasMsg))
+ {
+#ifndef _COMPACT
+ finishPrint();
+ removeEventHandler(pctxt);
+#endif
+ iRet=ooGkClientHandleRASMessage( pGkClient, pRasMsg );
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error: Failed to handle received RAS message\n");
+ //pGkClient->state = GkClientFailed;
+ }
+ memReset(pctxt);
+ }
+ else{
+ OOTRACEERR1("ERROR:Failed to decode received RAS message- ignoring"
+ "received message.\n");
+#ifndef _COMPACT
+ removeEventHandler(pctxt);
+#endif
+ memReset(pctxt);
+ return OO_FAILED;
+ }
+ return iRet;
+}
+
+
+
+
+/**
+ * Manage incoming RAS message.
+ */
+
+int ooGkClientHandleRASMessage(ooGkClient *pGkClient, H225RasMessage *pRasMsg)
+{
+ int iRet = OO_OK;
+ switch( pRasMsg->t)
+ {
+ case T_H225RasMessage_gatekeeperConfirm:
+ OOTRACEINFO1("Gatekeeper Confirmed (GCF) message received.\n");
+ iRet = ooGkClientHandleGatekeeperConfirm(pGkClient,
+ pRasMsg->u.gatekeeperConfirm);
+ break;
+ case T_H225RasMessage_gatekeeperReject:
+ OOTRACEINFO1("Gatekeeper Reject (GRJ) message received\n");
+ iRet = ooGkClientHandleGatekeeperReject(pGkClient,
+ pRasMsg->u.gatekeeperReject);
+ break;
+ case T_H225RasMessage_registrationConfirm:
+ OOTRACEINFO1("Registration Confirm (RCF) message received\n");
+ iRet = ooGkClientHandleRegistrationConfirm(pGkClient,
+ pRasMsg->u.registrationConfirm );
+ break;
+ case T_H225RasMessage_registrationReject:
+ OOTRACEINFO1("Registration Reject (RRJ) message received.\n");
+ iRet = ooGkClientHandleRegistrationReject(pGkClient,
+ pRasMsg->u.registrationReject);
+ break;
+ case T_H225RasMessage_infoRequest:
+ //ooRasSendIRR( psRasMsg->sMessage.u.infoRequest->requestSeqNum );
+ break;
+ case T_H225RasMessage_admissionConfirm:
+ OOTRACEINFO1("Admission Confirm (ACF) message received\n");
+ iRet = ooGkClientHandleAdmissionConfirm(pGkClient,
+ pRasMsg->u.admissionConfirm);
+ break;
+ case T_H225RasMessage_unregistrationRequest:
+ OOTRACEINFO1("UnRegistration Request (URQ) message received.\n");
+ iRet = ooGkClientHandleUnregistrationRequest(pGkClient,
+ pRasMsg->u.unregistrationRequest);
+ break;
+ case T_H225RasMessage_unregistrationConfirm:
+ OOTRACEINFO1("UnRegistration Confirm (UCF) message received.\n");
+ break;
+ case T_H225RasMessage_unregistrationReject:
+ OOTRACEINFO1("UnRegistration Reject (URJ) message received.\n");
+ break;
+ case T_H225RasMessage_admissionReject:
+ OOTRACEINFO1("Admission Reject (ARJ) message received.\n");
+ iRet = ooGkClientHandleAdmissionReject(pGkClient,
+ pRasMsg->u.admissionReject);
+ break;
+ case T_H225RasMessage_disengageConfirm:
+ iRet = ooGkClientHandleDisengageConfirm(pGkClient,
+ pRasMsg->u.disengageConfirm);
+ break;
+ case T_H225RasMessage_disengageReject:
+ case T_H225RasMessage_bandwidthConfirm:
+ case T_H225RasMessage_bandwidthReject:
+ case T_H225RasMessage_locationRequest:
+ case T_H225RasMessage_locationConfirm:
+ case T_H225RasMessage_locationReject:
+ case T_H225RasMessage_infoRequestResponse:
+ case T_H225RasMessage_nonStandardMessage:
+ case T_H225RasMessage_unknownMessageResponse:
+ case T_H225RasMessage_requestInProgress:
+ case T_H225RasMessage_resourcesAvailableIndicate:
+ case T_H225RasMessage_resourcesAvailableConfirm:
+ case T_H225RasMessage_infoRequestAck:
+ case T_H225RasMessage_infoRequestNak:
+ case T_H225RasMessage_serviceControlIndication:
+ case T_H225RasMessage_serviceControlResponse:
+ case T_H225RasMessage_admissionConfirmSequence:
+ default:
+ /* Unhandled RAS message */
+ iRet= OO_OK;
+ }
+
+ return iRet;
+}
+
+#ifndef _COMPACT
+void ooGkClientPrintMessage
+ (ooGkClient *pGkClient, ASN1OCTET *msg, ASN1UINT len)
+{
+ OOCTXT ctxt;
+ H225RasMessage rasMsg;
+ int ret;
+
+ initContext(&ctxt);
+ setPERBuffer(&ctxt, msg, len, TRUE);
+ initializePrintHandler(&printHandler, "Sending RAS Message");
+ setEventHandler(&ctxt, &printHandler);
+
+ ret = asn1PD_H225RasMessage(&ctxt, &rasMsg);
+ if(ret != ASN_OK)
+ {
+ OOTRACEERR1("Error: Failed to decode RAS message\n");
+ }
+ finishPrint();
+ freeContext(&ctxt);
+}
+#endif
+/**
+ * Encode and send RAS message.
+ */
+
+int ooGkClientSendMsg(ooGkClient *pGkClient, H225RasMessage *pRasMsg)
+{
+ ASN1OCTET msgBuf[MAXMSGLEN];
+ ASN1OCTET *msgPtr=NULL;
+ int iLen;
+ OOCTXT *pctxt = &pGkClient->msgCtxt;
+
+ setPERBuffer( pctxt, msgBuf, MAXMSGLEN, TRUE );
+ if ( ASN_OK == asn1PE_H225RasMessage(pctxt, pRasMsg) )
+ {
+ OOTRACEDBGC1("Ras message encoding - successful\n");
+ }
+ else {
+ OOTRACEERR1("Error: RAS message encoding failed\n");
+ return OO_FAILED;
+ }
+
+ msgPtr = encodeGetMsgPtr( pctxt, &iLen );
+ /* If gatekeeper specified or have been discovered */
+ if(pGkClient->gkMode == RasUseSpecificGatekeeper ||
+ pGkClient->discoveryComplete)
+ {
+ if(ASN_OK != ooSocketSendTo( pGkClient->rasSocket, msgPtr, iLen,
+ pGkClient->gkRasIP, pGkClient->gkRasPort))
+ {
+ OOTRACEERR1("Error sending RAS message\n");
+ return OO_FAILED;
+ }
+ }
+ else if(pGkClient->gkMode == RasDiscoverGatekeeper &&
+ !pGkClient->discoveryComplete) {
+ if(ASN_OK != ooSocketSendTo(pGkClient->rasSocket, msgPtr, iLen,
+ MULTICAST_GKADDRESS, MULTICAST_GKPORT))
+ {
+ OOTRACEERR1("Error sending multicast RAS message\n" );
+ return OO_FAILED;
+ }
+ }
+ else {/* should never go here */
+ OOTRACEERR1("Error: GkClient in invalid state.\n");
+ return OO_FAILED;
+ }
+#ifndef _COMPACT
+ ooGkClientPrintMessage(pGkClient, msgPtr, iLen);
+#endif
+ return OO_OK;
+}
+
+
+
+int ooGkClientSendGRQ(ooGkClient *pGkClient)
+{
+ int iRet;
+ H225RasMessage *pRasMsg=NULL;
+ H225GatekeeperRequest *pGkReq=NULL;
+ H225TransportAddress_ipAddress *pRasAddress;
+ OOCTXT *pctxt = &pGkClient->msgCtxt;
+ ooGkClientTimerCb *cbData=NULL;
+
+
+
+ /* Allocate memory for RAS message */
+ pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
+ if(!pRasMsg)
+ {
+ OOTRACEERR1("Error: Memory allocation for GRQ RAS message failed\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ pGkReq = (H225GatekeeperRequest*)memAlloc(pctxt,
+ sizeof(H225GatekeeperRequest));
+ if(!pGkReq)
+ {
+ OOTRACEERR1("Error:Memory allocation for GRQ failed\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memset(pGkReq, 0, sizeof(H225GatekeeperRequest));
+ pRasMsg->t = T_H225RasMessage_gatekeeperRequest;
+ pRasMsg->u.gatekeeperRequest = pGkReq;
+
+ /* Populate message structure */
+ pGkReq->requestSeqNum = pGkClient->requestSeqNum++;
+ if ( !pGkReq->requestSeqNum )
+ pGkReq->requestSeqNum = pGkClient->requestSeqNum++;
+
+ pGkReq->protocolIdentifier = gProtocolID;
+ pGkReq->m.nonStandardDataPresent=0;
+ pGkReq->rasAddress.t=T_H225TransportAddress_ipAddress; /* IPv4 address */
+ pRasAddress = (H225TransportAddress_ipAddress*)memAlloc(pctxt,
+ sizeof(H225TransportAddress_ipAddress));
+ if(!pRasAddress)
+ {
+ OOTRACEERR1("Error: Memory allocation for Ras Address of GRQ message "
+ "failed\n");
+ memReset(&pGkClient->msgCtxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+
+ ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pRasAddress->ip.data);
+
+ pRasAddress->ip.numocts = 4;
+ pRasAddress->port = pGkClient->localRASPort;
+ pGkReq->rasAddress.u.ipAddress = pRasAddress;
+
+ /* Pose as gateway or terminal as per config */
+ if(gH323ep.isGateway)
+ pGkReq->endpointType.m.gatewayPresent = TRUE;
+ else
+ pGkReq->endpointType.m.terminalPresent = TRUE;
+
+ pGkReq->endpointType.m.nonStandardDataPresent=0;
+ pGkReq->endpointType.m.vendorPresent=1;
+
+ ooGkClientFillVendor(pGkClient, &pGkReq->endpointType.vendor);
+
+
+ pGkReq->m.endpointAliasPresent=TRUE;
+ if(OO_OK != ooPopulateAliasList(&pGkClient->msgCtxt, gH323ep.aliases,
+ &pGkReq->endpointAlias))
+ {
+ OOTRACEERR1("Error Failed to fill alias information for GRQ message\n");
+ memReset(&pGkClient->msgCtxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error: Failed to send GRQ message\n");
+ memReset(&pGkClient->msgCtxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ OOTRACEINFO1("Sent GRQ message\n");
+ cbData = (ooGkClientTimerCb*) memAlloc
+ (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
+ if(!cbData)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory to GRQ timer callback\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ cbData->timerType = OO_GRQ_TIMER;
+ cbData->pGkClient = pGkClient;
+ if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
+ &ooGkClientGRQTimerExpired, pGkClient->grqTimeout,
+ cbData, FALSE))
+ {
+ OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
+ memFreePtr(&pGkClient->ctxt, cbData);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ return OO_OK;
+}
+
+int ooGkClientHandleGatekeeperReject
+ (ooGkClient *pGkClient, H225GatekeeperReject *pGatekeeperReject)
+{
+ unsigned int x=0;
+ DListNode *pNode = NULL;
+ OOTimer *pTimer = NULL;
+
+ if(pGkClient->gkMode == RasUseSpecificGatekeeper)
+ {
+ /* delete the corresponding GRQ timer */
+ for(x=0; x<pGkClient->timerList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->timerList, x);
+ pTimer = (OOTimer*)pNode->data;
+ if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_GRQ_TIMER)
+ {
+ memFreePtr(&pGkClient->ctxt, pTimer->cbData);
+ ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
+ OOTRACEDBGA1("Deleted GRQ Timer.\n");
+ break;
+ }
+ }
+
+ pGkClient->state = GkClientGkErr;
+ switch(pGatekeeperReject->rejectReason.t)
+ {
+ case T_H225GatekeeperRejectReason_resourceUnavailable:
+ OOTRACEERR1("Error: Gatekeeper Reject - Resource Unavailable\n");
+ break;
+ case T_H225GatekeeperRejectReason_terminalExcluded:
+ OOTRACEERR1("Error: Gatekeeper Reject - Terminal Excluded\n");
+ break;
+ case T_H225GatekeeperRejectReason_invalidRevision:
+ OOTRACEERR1("Error: Gatekeeper Reject - Invalid Revision\n");
+ break;
+ case T_H225GatekeeperRejectReason_undefinedReason:
+ OOTRACEERR1("Error: Gatekeeper Reject - Undefined Reason\n");
+ break;
+ case T_H225GatekeeperRejectReason_securityDenial:
+ OOTRACEERR1("Error: Gatekeeper Reject - Security Denial\n");
+ break;
+ case T_H225GatekeeperRejectReason_genericDataReason:
+ OOTRACEERR1("Error: Gatekeeper Reject - Generic Data Reason\n");
+ break;
+ case T_H225GatekeeperRejectReason_neededFeatureNotSupported:
+ OOTRACEERR1("Error: Gatekeeper Reject - Needed Feature Not "
+ "Supported\n");
+ break;
+ case T_H225GatekeeperRejectReason_securityError:
+ OOTRACEERR1("Error:Gatekeeper Reject - Security Error\n");
+ break;
+ default:
+ OOTRACEERR1("Error: Gatekeeper Reject - Invalid reason\n");
+ }
+ return OO_OK;
+ }
+ OOTRACEDBGB1("Gatekeeper Reject response received for multicast GRQ "
+ "request\n");
+ return OO_OK;
+
+}
+
+int ooGkClientHandleGatekeeperConfirm
+ (ooGkClient *pGkClient, H225GatekeeperConfirm *pGatekeeperConfirm)
+{
+ int iRet=0;
+ unsigned int x=0;
+ DListNode *pNode = NULL;
+ OOTimer *pTimer = NULL;
+ H225TransportAddress_ipAddress *pRasAddress;
+
+ if(pGkClient->discoveryComplete)
+ {
+ OOTRACEDBGB1("Ignoring GKConfirm as Gatekeeper has been discovered\n");
+ return OO_OK;
+ }
+
+ if(pGatekeeperConfirm->m.gatekeeperIdentifierPresent)
+ {
+ pGkClient->gkId.nchars = pGatekeeperConfirm->gatekeeperIdentifier.nchars;
+ pGkClient->gkId.data = (ASN116BITCHAR*)memAlloc(&pGkClient->ctxt,
+ sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
+ if(!pGkClient->gkId.data)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for GK ID data\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ memcpy(pGkClient->gkId.data,
+ pGatekeeperConfirm->gatekeeperIdentifier.data,
+ sizeof(ASN116BITCHAR)* pGkClient->gkId.nchars);
+ }
+ else{
+ OOTRACEERR1("ERROR:No Gatekeeper ID present in received GKConfirmed "
+ "message\n");
+ OOTRACEINFO1("Ignoring message and will retransmit GRQ after timeout\n");
+ return OO_FAILED;
+ }
+
+ /* Extract Gatekeeper's RAS address */
+ if(pGatekeeperConfirm->rasAddress.t != T_H225TransportAddress_ipAddress)
+ {
+ OOTRACEERR1("ERROR:Unsupported RAS address type in received Gk Confirm"
+ " message.\n");
+ pGkClient->state = GkClientGkErr;
+ return OO_FAILED;
+ }
+ pRasAddress = pGatekeeperConfirm->rasAddress.u.ipAddress;
+ sprintf(pGkClient->gkRasIP, "%d.%d.%d.%d", pRasAddress->ip.data[0],
+ pRasAddress->ip.data[1],
+ pRasAddress->ip.data[2],
+ pRasAddress->ip.data[3]);
+ pGkClient->gkRasPort = pRasAddress->port;
+
+ pGkClient->discoveryComplete = TRUE;
+ pGkClient->state = GkClientDiscovered;
+ OOTRACEINFO1("Gatekeeper Confirmed\n");
+
+
+ /* Delete the corresponding GRQ timer */
+ for(x=0; x<pGkClient->timerList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->timerList, x);
+ pTimer = (OOTimer*)pNode->data;
+ if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_GRQ_TIMER)
+ {
+ memFreePtr(&pGkClient->ctxt, pTimer->cbData);
+ ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
+ OOTRACEDBGA1("Deleted GRQ Timer.\n");
+ break;
+ }
+ }
+
+ iRet = ooGkClientSendRRQ(pGkClient, FALSE);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send initial RRQ\n");
+ return OO_FAILED;
+ }
+ return OO_OK;
+}
+
+/**
+ * Send RRQ.
+ */
+
+int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive)
+{
+ int iRet;
+ H225RasMessage *pRasMsg=NULL;
+ H225RegistrationRequest *pRegReq=NULL;
+ OOCTXT *pctxt=NULL;
+ H225TransportAddress *pTransportAddress=NULL;
+ H225TransportAddress_ipAddress *pIpAddress=NULL;
+ ooGkClientTimerCb *cbData =NULL;
+
+ pctxt = &pGkClient->msgCtxt;
+
+ pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
+ if(!pRasMsg)
+ {
+ OOTRACEERR1("Error: Memory allocation for RRQ RAS message failed\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ pRegReq = (H225RegistrationRequest*)memAlloc(pctxt,
+ sizeof(H225RegistrationRequest));
+ if(!pRegReq)
+ {
+ OOTRACEERR1("Error:Memory allocation for RRQ failed\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memset(pRegReq, 0, sizeof(H225RegistrationRequest));
+ pRasMsg->t = T_H225RasMessage_registrationRequest;
+ pRasMsg->u.registrationRequest = pRegReq;
+
+ pRegReq->protocolIdentifier = gProtocolID;
+ pRegReq->m.nonStandardDataPresent=0;
+ /* Populate CallSignal Address List*/
+ pTransportAddress = (H225TransportAddress*) memAlloc(pctxt,
+ sizeof(H225TransportAddress));
+ pIpAddress = (H225TransportAddress_ipAddress*) memAlloc(pctxt,
+ sizeof(H225TransportAddress_ipAddress));
+ if(!pTransportAddress || !pIpAddress)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for signalling address of "
+ "RRQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pTransportAddress->t = T_H225TransportAddress_ipAddress;
+ pTransportAddress->u.ipAddress = pIpAddress;
+ ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddress->ip.data);
+ pIpAddress->ip.numocts = 4;
+ pIpAddress->port = gH323ep.listenPort;
+
+ dListInit(&pRegReq->callSignalAddress);
+ dListAppend(pctxt, &pRegReq->callSignalAddress,
+ (void*)pTransportAddress);
+
+ /* Populate RAS Address List*/
+ pTransportAddress = NULL;
+ pIpAddress = NULL;
+ pTransportAddress = (H225TransportAddress*) memAlloc(pctxt,
+ sizeof(H225TransportAddress));
+ pIpAddress = (H225TransportAddress_ipAddress*) memAlloc(pctxt,
+ sizeof(H225TransportAddress_ipAddress));
+ if(!pTransportAddress || !pIpAddress)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for RAS address of "
+ "RRQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ pTransportAddress->t = T_H225TransportAddress_ipAddress;
+ pTransportAddress->u.ipAddress = pIpAddress;
+
+ ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddress->ip.data);
+
+ pIpAddress->ip.numocts = 4;
+ pIpAddress->port = pGkClient->localRASPort;
+
+ dListInit(&pRegReq->rasAddress);
+ dListAppend(pctxt, &pRegReq->rasAddress,
+ (void*)pTransportAddress);
+
+ /* Pose as gateway or terminal as per config */
+ if(gH323ep.isGateway)
+ pRegReq->terminalType.m.gatewayPresent = TRUE;
+ else
+ pRegReq->terminalType.m.terminalPresent = TRUE;
+
+ pRegReq->terminalType.m.vendorPresent=TRUE;
+ ooGkClientFillVendor(pGkClient, &pRegReq->terminalType.vendor );
+
+ pRegReq->m.terminalAliasPresent=TRUE;
+ if(OO_OK != ooPopulateAliasList(pctxt, gH323ep.aliases,
+ &pRegReq->terminalAlias))
+ {
+ OOTRACEERR1("Error filling alias for RRQ\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ pRegReq->m.gatekeeperIdentifierPresent=TRUE;
+ pRegReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
+ pRegReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc
+ (pctxt, pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
+ if(!pRegReq->gatekeeperIdentifier.data)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory for GKIdentifier in RRQ "
+ "message.\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memcpy(pRegReq->gatekeeperIdentifier.data, pGkClient->gkId.data,
+ pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
+
+ ooGkClientFillVendor(pGkClient, &pRegReq->endpointVendor);
+
+ pRegReq->m.willSupplyUUIEsPresent=TRUE;
+ pRegReq->willSupplyUUIEs=FALSE;
+
+ pRegReq->requestSeqNum = pGkClient->requestSeqNum++;
+ if(!pRegReq->requestSeqNum)
+ pRegReq->requestSeqNum = pGkClient->requestSeqNum++;
+
+ pRegReq->discoveryComplete= pGkClient->discoveryComplete;
+ pRegReq->m.keepAlivePresent=TRUE;
+ pRegReq->keepAlive= keepAlive;
+
+ /*
+ * Cisco Gatekeeper re-registration fix. Thanks to Mike Tubby (mike@tubby.org) 28feb2007
+ * Without this patch initial registration works, but re-registration fails!
+ *
+ * For light-weight re-registration, keepalive is set true
+ * GK needs rasAddress, keepAlive, endpointIdentifier, gatekeeperIdentifier,
+ * tokens, and timeToLive
+ * GK will ignore all other params if KeepAlive is set.
+ *
+ */
+ if(keepAlive) {
+ /* KeepAlive, re-registration message...
+ allocate storage for endpoint-identifier, and populate it from what the
+ GK told us from the previous RCF. Only allocate on the first pass thru here */
+ pRegReq->endpointIdentifier.data =
+ (ASN116BITCHAR*)memAlloc(pctxt, pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
+ if (pRegReq->endpointIdentifier.data) {
+ pRegReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
+ pRegReq->m.endpointIdentifierPresent = TRUE;
+ memcpy(pRegReq->endpointIdentifier.data, pGkClient->endpointId.data, pGkClient->endpointId.nchars*sizeof(ASN116BITCHAR));
+ OOTRACEINFO1("Sending RRQ for re-registration (with EndpointID)\n");
+ }
+ else {
+ OOTRACEERR1("Error: Failed to allocate memory for EndpointIdentifier in RRQ \n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ }
+
+ pRegReq->m.timeToLivePresent = TRUE;
+ pRegReq->timeToLive = pGkClient->regTimeout;
+
+ iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error: Failed to send RRQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ OOTRACEINFO1("Sent RRQ message \n");
+ /* Start RRQ Timer */
+ cbData = (ooGkClientTimerCb*) memAlloc
+ (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
+ if(!cbData)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory to RRQ timer callback\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ cbData->timerType = OO_RRQ_TIMER;
+ cbData->pGkClient = pGkClient;
+ if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
+ &ooGkClientRRQTimerExpired, pGkClient->rrqTimeout,
+ cbData, FALSE))
+ {
+ OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
+ memFreePtr(&pGkClient->ctxt, cbData);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ return OO_OK;
+}
+
+
+
+/**
+ * Manage incoming RCF message.
+ */
+
+int ooGkClientHandleRegistrationConfirm
+ (ooGkClient *pGkClient, H225RegistrationConfirm *pRegistrationConfirm)
+{
+ int i=0;
+ unsigned int x=0;
+ OOTimer *pTimer = NULL;
+ DListNode *pNode = NULL;
+ H225TransportAddress *pCallSigAddr=NULL;
+ ooGkClientTimerCb *cbData;
+ ASN1UINT regTTL=0;
+ /* Extract Endpoint Id */
+ pGkClient->endpointId.nchars =
+ pRegistrationConfirm->endpointIdentifier.nchars;
+ pGkClient->endpointId.data = (ASN116BITCHAR*)memAlloc(&pGkClient->ctxt,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+ if(!pGkClient->endpointId.data)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for endpoint Id.\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ memcpy(pGkClient->endpointId.data,
+ pRegistrationConfirm->endpointIdentifier.data,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+
+ /* Extract CallSignalling Address */
+ for(i=0; i<(int)pRegistrationConfirm->callSignalAddress.count; i++)
+ {
+ pNode = dListFindByIndex(&pRegistrationConfirm->callSignalAddress, i);
+ if(!pNode)
+ {
+ OOTRACEERR1("Error:Invalid Registration confirmed message\n");
+ OOTRACEINFO1("Ignoring RCF, will retransmit RRQ after timeout\n");
+ return OO_FAILED;
+ }
+ pCallSigAddr = (H225TransportAddress*)pNode->data;
+ if(pCallSigAddr->t != T_H225TransportAddress_ipAddress)
+ continue;
+ sprintf(pGkClient->gkCallSignallingIP, "%d.%d.%d.%d",
+ pCallSigAddr->u.ipAddress->ip.data[0],
+ pCallSigAddr->u.ipAddress->ip.data[1],
+ pCallSigAddr->u.ipAddress->ip.data[2],
+ pCallSigAddr->u.ipAddress->ip.data[3]);
+ pGkClient->gkCallSignallingPort = pCallSigAddr->u.ipAddress->port;
+ }
+
+ /* Update list of registered aliases*/
+ if(pRegistrationConfirm->m.terminalAliasPresent)
+ {
+ ooGkClientUpdateRegisteredAliases(pGkClient,
+ &pRegistrationConfirm->terminalAlias, TRUE);
+ }
+ else{/* Everything registered*/
+ ooGkClientUpdateRegisteredAliases(pGkClient, NULL, TRUE);
+ }
+
+ /* Is keepAlive supported */
+ if(pRegistrationConfirm->m.timeToLivePresent)
+ {
+ pGkClient->regTimeout = pRegistrationConfirm->timeToLive;
+ OOTRACEINFO2("Gatekeeper supports KeepAlive, Registration TTL is %d\n",
+ pRegistrationConfirm->timeToLive);
+
+ if(pGkClient->regTimeout > DEFAULT_TTL_OFFSET)
+ regTTL = pGkClient->regTimeout - DEFAULT_TTL_OFFSET;
+ else
+ regTTL = pGkClient->regTimeout;
+
+ cbData = (ooGkClientTimerCb*) memAlloc
+ (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
+ if(!cbData)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for Regisration timer."
+ "\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ cbData->timerType = OO_REG_TIMER;
+ cbData->pGkClient = pGkClient;
+ if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
+ &ooGkClientREGTimerExpired, regTTL,
+ cbData, FALSE))
+ {
+ OOTRACEERR1("Error:Unable to create REG timer.\n ");
+ memFreePtr(&pGkClient->ctxt, cbData);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ }
+ else{
+ pGkClient->regTimeout = 0;
+ OOTRACEINFO1("Gatekeeper does not support KeepAlive.\n");
+ }
+ /* Extract Pre-Granted ARQ */
+ if(pRegistrationConfirm->m.preGrantedARQPresent)
+ {
+ memcpy(&pGkClient->gkInfo.preGrantedARQ,
+ &pRegistrationConfirm->preGrantedARQ,
+ sizeof(H225RegistrationConfirm_preGrantedARQ));
+ }
+
+
+ /* First delete the corresponding RRQ timer */
+ pNode = NULL;
+ for(x=0; x<pGkClient->timerList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->timerList, x);
+ pTimer = (OOTimer*)pNode->data;
+ if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_RRQ_TIMER)
+ {
+ memFreePtr(&pGkClient->ctxt, pTimer->cbData);
+ ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
+ OOTRACEDBGA1("Deleted RRQ Timer.\n");
+ break;
+ }
+ }
+ pGkClient->state = GkClientRegistered;
+ if(pGkClient->callbacks.onReceivedRegistrationConfirm)
+ pGkClient->callbacks.onReceivedRegistrationConfirm(pRegistrationConfirm,
+ gH323ep.aliases);
+ return OO_OK;
+}
+
+int ooGkClientHandleRegistrationReject
+ (ooGkClient *pGkClient, H225RegistrationReject *pRegistrationReject)
+{
+ int iRet=0;
+ unsigned int x=0;
+ DListNode *pNode = NULL;
+ OOTimer *pTimer = NULL;
+ /* First delete the corresponding RRQ timer */
+ for(x=0; x<pGkClient->timerList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->timerList, x);
+ pTimer = (OOTimer*)pNode->data;
+ if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_RRQ_TIMER)
+ {
+ memFreePtr(&pGkClient->ctxt, pTimer->cbData);
+ ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
+ OOTRACEDBGA1("Deleted RRQ Timer.\n");
+ break;
+ }
+ }
+
+ switch(pRegistrationReject->rejectReason.t)
+ {
+ case T_H225RegistrationRejectReason_discoveryRequired:
+ OOTRACEINFO1("RRQ Rejected - Discovery Required\n");
+
+ pGkClient->discoveryComplete = FALSE;
+ pGkClient->state = GkClientIdle;
+ pGkClient->rrqRetries = 0;
+ pGkClient->grqRetries = 0;
+ if(OO_OK != ooGkClientSendGRQ(pGkClient))
+ {
+ OOTRACEERR1("Error:Failed to send GRQ message\n");
+ return OO_FAILED;
+ }
+ return OO_OK;
+ case T_H225RegistrationRejectReason_invalidRevision:
+ OOTRACEERR1("RRQ Rejected - Invalid Revision\n");
+ break;
+ case T_H225RegistrationRejectReason_invalidCallSignalAddress:
+ OOTRACEERR1("RRQ Rejected - Invalid CallSignalAddress\n");
+ break;
+ case T_H225RegistrationRejectReason_invalidRASAddress:
+ OOTRACEERR1("RRQ Rejected - Invalid RAS Address\n");
+ break;
+ case T_H225RegistrationRejectReason_duplicateAlias:
+ OOTRACEERR1("RRQ Rejected - Duplicate Alias\n");
+ break;
+ case T_H225RegistrationRejectReason_invalidTerminalType:
+ OOTRACEERR1("RRQ Rejected - Invalid Terminal Type\n");
+ break;
+ case T_H225RegistrationRejectReason_undefinedReason:
+ OOTRACEERR1("RRQ Rejected - Undefined Reason\n");
+ break;
+ case T_H225RegistrationRejectReason_transportNotSupported:
+ OOTRACEERR1("RRQ Rejected - Transport Not supported\n");
+ break;
+ case T_H225RegistrationRejectReason_transportQOSNotSupported:
+ OOTRACEERR1("RRQ Rejected - Transport QOS Not Supported\n");
+ break;
+ case T_H225RegistrationRejectReason_resourceUnavailable:
+ OOTRACEERR1("RRQ Rejected - Resource Unavailable\n");
+ break;
+ case T_H225RegistrationRejectReason_invalidAlias:
+ OOTRACEERR1("RRQ Rejected - Invalid Alias\n");
+ break;
+ case T_H225RegistrationRejectReason_securityDenial:
+ OOTRACEERR1("RRQ Rejected - Security Denial\n");
+ break;
+ case T_H225RegistrationRejectReason_fullRegistrationRequired:
+ OOTRACEINFO1("RRQ Rejected - Full Registration Required\n");
+ pGkClient->state = GkClientDiscovered;
+ pGkClient->rrqRetries = 0;
+ iRet = ooGkClientSendRRQ(pGkClient, 0); /* No keepAlive */
+ if(iRet != OO_OK){
+ OOTRACEERR1("\nError: Full Registration transmission failed\n");
+ return OO_FAILED;
+ }
+ return OO_OK;
+ case T_H225RegistrationRejectReason_additiveRegistrationNotSupported:
+ OOTRACEERR1("RRQ Rejected - Additive Registration Not Supported\n");
+ break;
+ case T_H225RegistrationRejectReason_invalidTerminalAliases:
+ OOTRACEERR1("RRQ Rejected - Invalid Terminal Aliases\n");
+ break;
+ case T_H225RegistrationRejectReason_genericDataReason:
+ OOTRACEERR1("RRQ Rejected - Generic Data Reason\n");
+ break;
+ case T_H225RegistrationRejectReason_neededFeatureNotSupported:
+ OOTRACEERR1("RRQ Rejected - Needed Feature Not Supported\n");
+ break;
+ case T_H225RegistrationRejectReason_securityError:
+ OOTRACEERR1("RRQ Rejected - Security Error\n");
+ break;
+ default:
+ OOTRACEINFO1("RRQ Rejected - Invalid Reason\n");
+ }
+ pGkClient->state = GkClientGkErr;
+ return OO_OK;
+}
+
+
+int ooGkClientSendURQ(ooGkClient *pGkClient, ooAliases *aliases)
+{
+ int iRet;
+ H225RasMessage *pRasMsg=NULL;
+ H225UnregistrationRequest *pUnregReq=NULL;
+ OOCTXT *pctxt=NULL;
+ H225TransportAddress *pTransportAddress=NULL;
+ H225TransportAddress_ipAddress *pIpAddress=NULL;
+
+ pctxt = &pGkClient->msgCtxt;
+
+ OOTRACEDBGA1("Building Unregistration Request message\n");
+
+ pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
+ if(!pRasMsg)
+ {
+ OOTRACEERR1("Error: Memory allocation for URQ RAS message failed\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ pUnregReq = (H225UnregistrationRequest*)memAlloc(pctxt,
+ sizeof(H225UnregistrationRequest));
+ if(!pUnregReq)
+ {
+ OOTRACEERR1("Error:Memory allocation for URQ failed\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memset(pUnregReq, 0, sizeof(H225UnregistrationRequest));
+ pRasMsg->t = T_H225RasMessage_unregistrationRequest;
+ pRasMsg->u.unregistrationRequest = pUnregReq;
+
+ pUnregReq->requestSeqNum = pGkClient->requestSeqNum++;
+ if(!pUnregReq->requestSeqNum)
+ pUnregReq->requestSeqNum = pGkClient->requestSeqNum++;
+
+
+
+ /* Populate CallSignal Address List*/
+ pTransportAddress = (H225TransportAddress*) memAlloc(pctxt,
+ sizeof(H225TransportAddress));
+ pIpAddress = (H225TransportAddress_ipAddress*) memAlloc(pctxt,
+ sizeof(H225TransportAddress_ipAddress));
+ if(!pTransportAddress || !pIpAddress)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for signalling address of "
+ "RRQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pTransportAddress->t = T_H225TransportAddress_ipAddress;
+ pTransportAddress->u.ipAddress = pIpAddress;
+ ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddress->ip.data);
+ pIpAddress->ip.numocts = 4;
+ pIpAddress->port = gH323ep.listenPort;
+
+ dListInit(&pUnregReq->callSignalAddress);
+ dListAppend(pctxt, &pUnregReq->callSignalAddress,
+ (void*)pTransportAddress);
+
+ /* Populate Endpoint Identifier */
+ pUnregReq->m.endpointIdentifierPresent = TRUE;
+ pUnregReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
+ pUnregReq->endpointIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+ if(!pUnregReq->endpointIdentifier.data)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory for EndPoint Id in URQ "
+ "message.\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memcpy((void*)pUnregReq->endpointIdentifier.data,
+ (void*)pGkClient->endpointId.data,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+
+ /* Populate gatekeeper identifier */
+ pUnregReq->m.gatekeeperIdentifierPresent = TRUE;
+ pUnregReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
+ pUnregReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
+ sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
+ if(!pUnregReq->gatekeeperIdentifier.data)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for GKID of URQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memcpy((void*)pUnregReq->gatekeeperIdentifier.data,
+ (void*)pGkClient->gkId.data,
+ sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
+
+ /* Check whether specific aliases are to be unregistered*/
+ if(aliases)
+ {
+ pUnregReq->m.endpointAliasPresent = TRUE;
+ ooPopulateAliasList(pctxt, aliases, &pUnregReq->endpointAlias);
+ }
+
+
+ iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send UnregistrationRequest message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pGkClient->state = GkClientUnregistered;
+ OOTRACEINFO1("Unregistration Request message sent.\n");
+
+ return OO_OK;
+}
+
+
+
+int ooGkClientHandleUnregistrationRequest
+ (ooGkClient *pGkClient, H225UnregistrationRequest * punregistrationRequest)
+{
+ int iRet=0;
+
+ /* Lets first send unregistration confirm message back to gatekeeper*/
+ ooGkClientSendUnregistrationConfirm(pGkClient,
+ punregistrationRequest->requestSeqNum);
+
+ if(punregistrationRequest->m.endpointAliasPresent)
+ {
+ OOTRACEINFO1("Gatekeeper requested a list of aliases be unregistered\n");
+ ooGkClientUpdateRegisteredAliases(pGkClient,
+ &punregistrationRequest->endpointAlias, FALSE);
+ }
+ else{
+
+ OOTRACEINFO1("Gatekeeper requested a all aliases to be unregistered\n");
+ ooGkClientUpdateRegisteredAliases(pGkClient, NULL, FALSE);
+ /* Send a fresh Registration request and if that fails, go back to
+ Gatekeeper discovery.
+ */
+ OOTRACEINFO1("Sending fresh RRQ - as unregistration request received\n");
+ pGkClient->rrqRetries = 0;
+ pGkClient->state = GkClientDiscovered;
+
+ iRet = ooGkClientSendRRQ(pGkClient, 0);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error: Failed to send RRQ message\n");
+ return OO_FAILED;
+ }
+ }
+
+
+ if(pGkClient->callbacks.onReceivedUnregistrationRequest)
+ pGkClient->callbacks.onReceivedUnregistrationRequest(
+ punregistrationRequest, gH323ep.aliases);
+ return OO_OK;
+}
+
+int ooGkClientSendUnregistrationConfirm(ooGkClient *pGkClient, unsigned reqNo)
+{
+ int iRet = OO_OK;
+ OOCTXT *pctxt = &pGkClient->msgCtxt;
+ H225RasMessage *pRasMsg=NULL;
+ H225UnregistrationConfirm *pUCF=NULL;
+
+ pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
+ pUCF = (H225UnregistrationConfirm*)memAlloc(pctxt,
+ sizeof(H225UnregistrationConfirm));
+ if(!pRasMsg || !pUCF)
+ {
+ OOTRACEERR1("Error: Memory allocation for UCF RAS message failed\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pRasMsg->t = T_H225RasMessage_unregistrationConfirm;
+ pRasMsg->u.unregistrationConfirm = pUCF;
+ memset(pUCF, 0, sizeof(H225UnregistrationConfirm));
+
+ pUCF->requestSeqNum = reqNo;
+
+ iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send UnregistrationConfirm message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ OOTRACEINFO1("Unregistration Confirm message sent for \n");
+ memReset(pctxt);
+
+ return OO_OK;
+}
+
+
+
+
+int ooGkClientSendAdmissionRequest
+ (ooGkClient *pGkClient, OOH323CallData *call, ASN1BOOL retransmit)
+{
+ int iRet = 0;
+ unsigned int x;
+ DListNode *pNode;
+ ooGkClientTimerCb *cbData=NULL;
+ H225RasMessage *pRasMsg=NULL;
+ OOCTXT* pctxt;
+ H225AdmissionRequest *pAdmReq=NULL;
+ H225TransportAddress_ipAddress *pIpAddressLocal =NULL, *pIpAddressRemote=NULL;
+ ooAliases *destAliases = NULL, *srcAliases=NULL;
+ RasCallAdmissionInfo *pCallAdmInfo=NULL;
+ pctxt = &pGkClient->msgCtxt;
+
+ OOTRACEDBGA3("Building Admission Request for call (%s, %s)\n",
+ call->callType, call->callToken);
+ pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
+ if(!pRasMsg)
+ {
+ OOTRACEERR3("Error:Memory - ooGkClientSendAdmissionRequest - "
+ "pRasMsg(%s, %s)\n", call->callType, call->callToken);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pRasMsg->t = T_H225RasMessage_admissionRequest;
+ pAdmReq = (H225AdmissionRequest*) memAlloc(pctxt,
+ sizeof(H225AdmissionRequest));
+ if(!pAdmReq)
+ {
+ OOTRACEERR3("Error:Memory - ooGkClientSendAdmissionRequest - "
+ "pAdmReq(%s, %s)\n", call->callType, call->callToken);
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memset(pAdmReq, 0, sizeof(H225AdmissionRequest));
+ pRasMsg->u.admissionRequest = pAdmReq;
+
+ /* Populate call signalling addresses */
+ pIpAddressLocal = (H225TransportAddress_ipAddress*)memAlloc(pctxt,
+ sizeof(H225TransportAddress_ipAddress));
+ if(!ooUtilsIsStrEmpty(call->remoteIP))
+ pIpAddressRemote = (H225TransportAddress_ipAddress*)memAlloc(pctxt,
+ sizeof(H225TransportAddress_ipAddress));
+
+ if(!pIpAddressLocal || (!ooUtilsIsStrEmpty(call->remoteIP) && (!pIpAddressRemote)))
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for Call Signalling "
+ "Addresses of ARQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddressLocal->ip.data);
+
+ pIpAddressLocal->ip.numocts = 4;
+ pIpAddressLocal->port = gH323ep.listenPort;
+
+ if(!ooUtilsIsStrEmpty(call->remoteIP))
+ {
+ ooSocketConvertIpToNwAddr(call->remoteIP, pIpAddressRemote->ip.data);
+ pIpAddressRemote->ip.numocts = 4;
+ pIpAddressRemote->port = call->remotePort;
+ }
+
+ if(!strcmp(call->callType, "incoming"))
+ {
+ pAdmReq->m.destCallSignalAddressPresent = TRUE;
+ pAdmReq->destCallSignalAddress.t = T_H225TransportAddress_ipAddress;
+ pAdmReq->destCallSignalAddress.u.ipAddress = pIpAddressLocal;
+ if(!ooUtilsIsStrEmpty(call->remoteIP))
+ {
+ pAdmReq->m.srcCallSignalAddressPresent = TRUE;
+ pAdmReq->srcCallSignalAddress.t = T_H225TransportAddress_ipAddress;
+ pAdmReq->srcCallSignalAddress.u.ipAddress = pIpAddressRemote;
+ }
+ }
+ else {
+ pAdmReq->m.srcCallSignalAddressPresent = TRUE;
+ pAdmReq->srcCallSignalAddress.t = T_H225TransportAddress_ipAddress;
+ pAdmReq->srcCallSignalAddress.u.ipAddress = pIpAddressLocal;
+ if(!ooUtilsIsStrEmpty(call->remoteIP))
+ {
+ pAdmReq->m.destCallSignalAddressPresent = TRUE;
+ pAdmReq->destCallSignalAddress.t = T_H225TransportAddress_ipAddress;
+ pAdmReq->destCallSignalAddress.u.ipAddress = pIpAddressRemote;
+ }
+ }
+
+ /* Populate seq number */
+ pAdmReq->requestSeqNum = pGkClient->requestSeqNum++;
+ if(!pAdmReq->requestSeqNum)
+ pAdmReq->requestSeqNum = pGkClient->requestSeqNum++;
+
+ /* Populate call type - For now only PointToPoint supported*/
+ pAdmReq->callType.t = T_H225CallType_pointToPoint;
+
+ /* Add call model to message*/
+ pAdmReq->m.callModelPresent = 1;
+ if(OO_TESTFLAG(call->flags, OO_M_GKROUTED))
+ pAdmReq->callModel.t = T_H225CallModel_gatekeeperRouted;
+ else
+ pAdmReq->callModel.t = T_H225CallModel_direct;
+
+ /* Populate Endpoint Identifier */
+ pAdmReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
+ pAdmReq->endpointIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+ if(!pAdmReq->endpointIdentifier.data)
+ {
+ OOTRACEERR3("Error:Memory - ooGkClientSendAdmissionRequest - "
+ "endpointIdentifier.data(%s, %s)\n", call->callType,
+ call->callToken);
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memcpy((void*)pAdmReq->endpointIdentifier.data,
+ (void*)pGkClient->endpointId.data,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+
+ /* Get Destination And source aliases for call - */
+ if(!strcmp(call->callType, "incoming"))
+ {
+ if(call->ourAliases)
+ destAliases = call->ourAliases;
+ else
+ destAliases = gH323ep.aliases;
+
+ srcAliases = call->remoteAliases;
+ }
+ else {
+ if(call->ourAliases)
+ srcAliases = call->ourAliases;
+ else
+ srcAliases = gH323ep.aliases;
+
+ destAliases = call->remoteAliases;
+ }
+
+ /* Populate destination info */
+ if(destAliases)
+ {
+ pAdmReq->m.destinationInfoPresent = 1;
+ if(OO_OK != ooPopulateAliasList(&pGkClient->msgCtxt, destAliases,
+ &pAdmReq->destinationInfo))
+ {
+ OOTRACEERR1("Error:Failed to populate destination aliases - "
+ "ARQ message\n");
+ pGkClient->state = GkClientFailed;
+ memReset(pctxt);
+ return OO_FAILED;
+ }
+ }
+
+ /* Populate Source Info */
+ if(srcAliases)
+ {
+ iRet = ooPopulateAliasList(&pGkClient->msgCtxt, srcAliases,
+ &pAdmReq->srcInfo);
+ if(OO_OK != iRet)
+ {
+ OOTRACEERR1("Error:Failed to populate source aliases -ARQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ }
+
+ /* Populate bandwidth*/
+ pAdmReq->bandWidth = DEFAULT_BW_REQUEST;
+ /* Populate call Reference */
+ pAdmReq->callReferenceValue = call->callReference;
+
+ /* populate conferenceID */
+ memcpy((void*)&pAdmReq->conferenceID, (void*)&call->confIdentifier,
+ sizeof(H225ConferenceIdentifier));
+ /*populate answerCall */
+ if(!strcmp(call->callType, "incoming"))
+ pAdmReq->answerCall = TRUE;
+ else
+ pAdmReq->answerCall = FALSE;
+
+ /* Populate CanMapAlias */
+ pAdmReq->m.canMapAliasPresent = TRUE;
+ pAdmReq->canMapAlias = FALSE;
+
+ /* Populate call identifier */
+ pAdmReq->m.callIdentifierPresent = TRUE;
+ memcpy((void*)&pAdmReq->callIdentifier, (void*)&call->callIdentifier,
+ sizeof(H225CallIdentifier));
+
+ /* Populate Gatekeeper Id */
+ pAdmReq->m.gatekeeperIdentifierPresent = TRUE;
+ pAdmReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
+ pAdmReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
+ sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
+ if(!pAdmReq->gatekeeperIdentifier.data)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for GKID of ARQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memcpy((void*)pAdmReq->gatekeeperIdentifier.data,
+ (void*)pGkClient->gkId.data,
+ sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
+
+ pAdmReq->m.willSupplyUUIEsPresent = 1;
+ pAdmReq->willSupplyUUIEs = FALSE;
+
+ /* Create RasCallAdmissionInfo */
+ if(!retransmit)
+ {
+ pCallAdmInfo = (RasCallAdmissionInfo*)memAlloc(&pGkClient->ctxt,
+ sizeof(RasCallAdmissionInfo));
+ if(!pCallAdmInfo)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory for new CallAdmission"
+ " Info entry\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ pCallAdmInfo->call = call;
+ pCallAdmInfo->retries = 0;
+ pCallAdmInfo->requestSeqNum = pAdmReq->requestSeqNum;
+ dListAppend(&pGkClient->ctxt, &pGkClient->callsPendingList,pCallAdmInfo);
+ }
+ else{
+ for(x=0; x<pGkClient->callsPendingList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
+ pCallAdmInfo = (RasCallAdmissionInfo*)pNode->data;
+ if(pCallAdmInfo->call->callReference == call->callReference)
+ {
+ pCallAdmInfo->requestSeqNum = pAdmReq->requestSeqNum;
+ break;
+ }
+ }
+ }
+
+ iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send AdmissionRequest message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ OOTRACEINFO3("Admission Request message sent for (%s, %s)\n",
+ call->callType, call->callToken);
+ memReset(pctxt);
+
+ /* Add ARQ timer */
+ cbData = (ooGkClientTimerCb*) memAlloc
+ (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
+ if(!cbData)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for Regisration timer."
+ "\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ cbData->timerType = OO_ARQ_TIMER;
+ cbData->pGkClient = pGkClient;
+ cbData->pAdmInfo = pCallAdmInfo;
+ if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
+ &ooGkClientARQTimerExpired, pGkClient->arqTimeout,
+ cbData, FALSE))
+ {
+ OOTRACEERR1("Error:Unable to create ARQ timer.\n ");
+ memFreePtr(&pGkClient->ctxt, cbData);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ return OO_OK;
+}
+
+/**
+ * Manage incoming ACF message.
+ */
+
+int ooGkClientHandleAdmissionConfirm
+ (ooGkClient *pGkClient, H225AdmissionConfirm *pAdmissionConfirm)
+{
+ RasCallAdmissionInfo* pCallAdmInfo=NULL;
+ unsigned int x, y;
+ DListNode *pNode, *pNode1=NULL;
+ H225TransportAddress_ipAddress * ipAddress=NULL;
+ OOTimer *pTimer = NULL;
+ char ip[20];
+
+ /* Search call in pending calls list */
+ for(x=0 ; x<pGkClient->callsPendingList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
+ pCallAdmInfo = (RasCallAdmissionInfo*) pNode->data;
+ if(pCallAdmInfo->requestSeqNum == pAdmissionConfirm->requestSeqNum)
+ {
+ OOTRACEDBGC3("Found Pending call(%s, %s)\n",
+ pCallAdmInfo->call->callType,
+ pCallAdmInfo->call->callToken);
+ /* Populate Remote IP */
+ if(pAdmissionConfirm->destCallSignalAddress.t !=
+ T_H225TransportAddress_ipAddress)
+ {
+ OOTRACEERR1("Error:Destination Call Signal Address provided by"
+ "Gatekeeper is not an IPv4 address\n");
+ OOTRACEINFO1("Ignoring ACF, will wait for timeout and retransmit "
+ "ARQ\n");
+ return OO_FAILED;
+ }
+ ipAddress = pAdmissionConfirm->destCallSignalAddress.u.ipAddress;
+
+ sprintf(ip, "%d.%d.%d.%d", ipAddress->ip.data[0],
+ ipAddress->ip.data[1],
+ ipAddress->ip.data[2],
+ ipAddress->ip.data[3]);
+ if(strcmp(ip, "0.0.0.0"))
+ strcpy(pCallAdmInfo->call->remoteIP, ip);
+ pCallAdmInfo->call->remotePort = ipAddress->port;
+ /* Update call model */
+ if(pAdmissionConfirm->callModel.t == T_H225CallModel_direct)
+ {
+ if(OO_TESTFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED))
+ {
+ OOTRACEINFO3("Gatekeeper changed call model from GkRouted to "
+ "direct. (%s, %s)\n", pCallAdmInfo->call->callType,
+ pCallAdmInfo->call->callToken);
+ OO_CLRFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED);
+ }
+ }
+
+ if(pAdmissionConfirm->callModel.t == T_H225CallModel_gatekeeperRouted)
+ {
+ if(!OO_TESTFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED))
+ {
+ OOTRACEINFO3("Gatekeeper changed call model from direct to "
+ "GkRouted. (%s, %s)\n",
+ pCallAdmInfo->call->callType,
+ pCallAdmInfo->call->callToken);
+ OO_SETFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED);
+ }
+ }
+
+ /* Delete ARQ timer */
+ for(y=0; y<pGkClient->timerList.count; y++)
+ {
+ pNode1 = dListFindByIndex(&pGkClient->timerList, y);
+ pTimer = (OOTimer*)pNode1->data;
+ if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_ARQ_TIMER)
+ {
+ if(((ooGkClientTimerCb*)pTimer->cbData)->pAdmInfo ==
+ pCallAdmInfo)
+ {
+ memFreePtr(&pGkClient->ctxt, pTimer->cbData);
+ ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList,
+ pTimer);
+ OOTRACEDBGA1("Deleted ARQ Timer.\n");
+ break;
+ }
+ }
+ }
+ OOTRACEINFO3("Admission Confirm message received for (%s, %s)\n",
+ pCallAdmInfo->call->callType,
+ pCallAdmInfo->call->callToken);
+ ooH323CallAdmitted( pCallAdmInfo->call);
+ dListRemove(&pGkClient->callsPendingList, pNode);
+ dListAppend(&pGkClient->ctxt, &pGkClient->callsAdmittedList,
+ pNode->data);
+ memFreePtr(&pGkClient->ctxt, pNode);
+ return OO_OK;
+ break;
+ }
+ else
+ {
+ pNode = pNode->next;
+ }
+ }
+ OOTRACEERR1("Error: Failed to process ACF as there is no corresponding "
+ "pending call\n");
+ return OO_OK;
+}
+
+
+int ooGkClientHandleAdmissionReject
+ (ooGkClient *pGkClient, H225AdmissionReject *pAdmissionReject)
+{
+ RasCallAdmissionInfo* pCallAdmInfo=NULL;
+ unsigned int x;
+ DListNode *pNode=NULL;
+ OOH323CallData *call=NULL;
+
+ /* Search call in pending calls list */
+ for(x=0 ; x<pGkClient->callsPendingList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
+ pCallAdmInfo = (RasCallAdmissionInfo*) pNode->data;
+ if(pCallAdmInfo->requestSeqNum == pAdmissionReject->requestSeqNum)
+ break;
+ pNode = NULL;
+ pCallAdmInfo = NULL;
+ }
+
+ if(!pCallAdmInfo)
+ {
+ OOTRACEWARN2("Received admission reject with request number %d can not"
+ " be matched with any pending call.\n",
+ pAdmissionReject->requestSeqNum);
+ return OO_OK;
+ }
+ else{
+ call = pCallAdmInfo->call;
+ dListRemove(&pGkClient->callsPendingList, pNode);
+ memFreePtr(&pGkClient->ctxt, pCallAdmInfo);
+ memFreePtr(&pGkClient->ctxt, pNode);
+ }
+
+ OOTRACEINFO4("Admission Reject message received with reason code %d for "
+ "(%s, %s)\n", pAdmissionReject->rejectReason.t, call->callType,
+ call->callToken);
+
+ call->callState = OO_CALL_CLEAR;
+
+ switch(pAdmissionReject->rejectReason.t)
+ {
+ case T_H225AdmissionRejectReason_calledPartyNotRegistered:
+ call->callEndReason = OO_REASON_GK_NOCALLEDUSER;
+ break;
+ case T_H225AdmissionRejectReason_invalidPermission:
+ case T_H225AdmissionRejectReason_requestDenied:
+ case T_H225AdmissionRejectReason_undefinedReason:
+ call->callEndReason = OO_REASON_GK_CLEARED;
+ break;
+ case T_H225AdmissionRejectReason_callerNotRegistered:
+ call->callEndReason = OO_REASON_GK_NOCALLERUSER;
+ break;
+ case T_H225AdmissionRejectReason_exceedsCallCapacity:
+ case T_H225AdmissionRejectReason_resourceUnavailable:
+ call->callEndReason = OO_REASON_GK_NORESOURCES;
+ break;
+ case T_H225AdmissionRejectReason_noRouteToDestination:
+ case T_H225AdmissionRejectReason_unallocatedNumber:
+ call->callEndReason = OO_REASON_GK_UNREACHABLE;
+ break;
+ case T_H225AdmissionRejectReason_routeCallToGatekeeper:
+ case T_H225AdmissionRejectReason_invalidEndpointIdentifier:
+ case T_H225AdmissionRejectReason_securityDenial:
+ case T_H225AdmissionRejectReason_qosControlNotSupported:
+ case T_H225AdmissionRejectReason_incompleteAddress:
+ case T_H225AdmissionRejectReason_aliasesInconsistent:
+ case T_H225AdmissionRejectReason_routeCallToSCN:
+ case T_H225AdmissionRejectReason_collectDestination:
+ case T_H225AdmissionRejectReason_collectPIN:
+ case T_H225AdmissionRejectReason_genericDataReason:
+ case T_H225AdmissionRejectReason_neededFeatureNotSupported:
+ case T_H225AdmissionRejectReason_securityErrors:
+ case T_H225AdmissionRejectReason_securityDHmismatch:
+ case T_H225AdmissionRejectReason_extElem1:
+ call->callEndReason = OO_REASON_GK_CLEARED;
+ break;
+ }
+
+ return OO_OK;
+}
+
+/**
+ * This function is invoked to request call disengage to gatekeeper.
+ *
+ * @param szCallToken Call token.
+ *
+ * @return Completion status - 0 on success, -1 on failure
+ */
+
+int ooGkClientSendDisengageRequest(ooGkClient *pGkClient, OOH323CallData *call)
+{
+ int iRet = 0;
+ unsigned int x;
+ H225RasMessage *pRasMsg=NULL;
+ OOCTXT *pctxt = NULL;
+ DListNode *pNode = NULL;
+ H225DisengageRequest * pDRQ = NULL;
+ RasCallAdmissionInfo* pCallAdmInfo=NULL;
+ pctxt = &pGkClient->msgCtxt;
+
+ OOTRACEINFO3("Sending disengage Request for call. (%s, %s)\n",
+ call->callType, call->callToken);
+
+ pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
+ if(!pRasMsg)
+ {
+ OOTRACEERR1("Error: Memory allocation for DRQ RAS message failed\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ pRasMsg->t = T_H225RasMessage_disengageRequest;
+ pDRQ = (H225DisengageRequest*) memAlloc(pctxt,
+ sizeof(H225DisengageRequest));
+ if(!pDRQ)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory for DRQ message\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+
+ memset(pDRQ, 0, sizeof(H225DisengageRequest));
+ pRasMsg->u.disengageRequest = pDRQ;
+
+ pDRQ->requestSeqNum = pGkClient->requestSeqNum++;
+ if(!pDRQ->requestSeqNum )
+ pDRQ->requestSeqNum = pGkClient->requestSeqNum++;
+
+
+ pDRQ->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
+ pDRQ->endpointIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+ if(!pDRQ->endpointIdentifier.data)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory for EndPoint Id in DRQ "
+ "message.\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memcpy((void*)pDRQ->endpointIdentifier.data,
+ (void*)pGkClient->endpointId.data,
+ sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+
+ memcpy((void*)&pDRQ->conferenceID, (void*)&call->confIdentifier,
+ sizeof(H225ConferenceIdentifier));
+
+ pDRQ->callReferenceValue = call->callReference;
+
+ pDRQ->disengageReason.t = T_H225DisengageReason_normalDrop;
+
+ pDRQ->m.answeredCallPresent = 1;
+ if(!strcmp(call->callType, "incoming"))
+ pDRQ->answeredCall = 1;
+ else
+ pDRQ->answeredCall = 0;
+
+ pDRQ->m.callIdentifierPresent = 1;
+ memcpy((void*)&pDRQ->callIdentifier, (void*)&call->callIdentifier,
+ sizeof(H225CallIdentifier));
+ pDRQ->m.gatekeeperIdentifierPresent = 1;
+ pDRQ->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
+ pDRQ->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc
+ (pctxt, pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
+ if(!pDRQ->gatekeeperIdentifier.data)
+ {
+ OOTRACEERR1("Error:Failed to allocate memory for GKId in DRQ.\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ memcpy(pDRQ->gatekeeperIdentifier.data, pGkClient->gkId.data,
+ pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
+
+ pDRQ->m.terminationCausePresent = 1;
+ pDRQ->terminationCause.t = T_H225CallTerminationCause_releaseCompleteCauseIE;
+ pDRQ->terminationCause.u.releaseCompleteCauseIE =
+ (H225CallTerminationCause_releaseCompleteCauseIE*)memAlloc(pctxt,
+ sizeof(H225CallTerminationCause_releaseCompleteCauseIE));
+ if(!pDRQ->terminationCause.u.releaseCompleteCauseIE)
+ {
+ OOTRACEERR1("Error: Failed to allocate memory for cause ie in DRQ.\n");
+ memReset(pctxt);
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pDRQ->terminationCause.u.releaseCompleteCauseIE->numocts =
+ strlen("Call Ended");
+ strcpy(pDRQ->terminationCause.u.releaseCompleteCauseIE->data, "Call Ended");
+
+ iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
+ if(iRet != OO_OK)
+ {
+ OOTRACEERR1("Error: Failed to send DRQ message\n");
+ pGkClient->state = GkClientFailed;
+ }
+
+
+
+ /* Search call in admitted calls list */
+ for(x=0 ; x<pGkClient->callsAdmittedList.count ; x++)
+ {
+ pNode = (DListNode*)dListFindByIndex(&pGkClient->callsAdmittedList, x);
+ pCallAdmInfo = (RasCallAdmissionInfo*) pNode->data;
+ if(pCallAdmInfo->call->callReference == call->callReference)
+ {
+ dListRemove( &pGkClient->callsAdmittedList, pNode);
+ memFreePtr(&pGkClient->ctxt, pNode->data);
+ memFreePtr(&pGkClient->ctxt, pNode);
+ break;
+ }
+ }
+ return iRet;
+}
+
+int ooGkClientHandleDisengageConfirm
+ (ooGkClient *pGkClient, H225DisengageConfirm *pDCF)
+{
+ OOTRACEINFO1("Received disengage confirm\n");
+ return OO_OK;
+}
+
+int ooGkClientRRQTimerExpired(void*pdata)
+{
+ int ret=0;
+ ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
+ ooGkClient *pGkClient = cbData->pGkClient;
+ OOTRACEDBGA1("Gatekeeper client RRQ timer expired.\n");
+
+ if(pGkClient->rrqRetries < OO_MAX_RRQ_RETRIES)
+ {
+ ret = ooGkClientSendRRQ(pGkClient, 0);
+ if(ret != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send RRQ message\n");
+
+ return OO_FAILED;
+ }
+ pGkClient->rrqRetries++;
+ memFreePtr(&pGkClient->ctxt, cbData);
+ return OO_OK;
+ }
+ memFreePtr(&pGkClient->ctxt, cbData);
+ OOTRACEERR1("Error:Failed to register with gatekeeper\n");
+ pGkClient->state = GkClientGkErr;
+ return OO_FAILED;
+}
+
+int ooGkClientGRQTimerExpired(void* pdata)
+{
+ int ret=0;
+ ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
+ ooGkClient *pGkClient = cbData->pGkClient;
+
+ OOTRACEDBGA1("Gatekeeper client GRQ timer expired.\n");
+
+ memFreePtr(&pGkClient->ctxt, cbData);
+
+ if(pGkClient->grqRetries < OO_MAX_GRQ_RETRIES)
+ {
+ ret = ooGkClientSendGRQ(pGkClient);
+ if(ret != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send GRQ message\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ pGkClient->grqRetries++;
+ return OO_OK;
+ }
+
+ OOTRACEERR1("Error:Gatekeeper could not be found\n");
+ pGkClient->state = GkClientGkErr;
+ return OO_FAILED;
+}
+
+int ooGkClientREGTimerExpired(void *pdata)
+{
+ int ret=0;
+ ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
+ ooGkClient *pGkClient = cbData->pGkClient;
+ OOTRACEDBGA1("Gatekeeper client additive registration timer expired\n");
+ memFreePtr(&pGkClient->ctxt, cbData);
+ ret = ooGkClientSendRRQ(pGkClient, TRUE);
+ if(ret != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send Additive RRQ message\n");
+ pGkClient->state = GkClientFailed;
+ return OO_FAILED;
+ }
+ return OO_OK;
+}
+
+int ooGkClientARQTimerExpired(void* pdata)
+{
+ int ret=0;
+ ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
+ ooGkClient *pGkClient = cbData->pGkClient;
+ RasCallAdmissionInfo *pAdmInfo = cbData->pAdmInfo;
+
+ OOTRACEDBGA1("Gatekeeper client ARQ timer expired.\n");
+ memFreePtr(&pGkClient->ctxt, cbData);
+
+ if(pAdmInfo->retries < OO_MAX_ARQ_RETRIES)
+ {
+ ret = ooGkClientSendAdmissionRequest(pGkClient, pAdmInfo->call, TRUE);
+ if(ret != OO_OK)
+ {
+ OOTRACEERR1("Error:Failed to send ARQ message\n");
+ return OO_FAILED;
+ }
+ pAdmInfo->retries++;
+ return OO_OK;
+ }
+
+ OOTRACEERR1("Error:Gatekeeper not responding to ARQ\n");
+ pGkClient->state = GkClientGkErr;
+ return OO_FAILED;
+}
+
+int ooGkClientCleanCall(ooGkClient *pGkClient, OOH323CallData *call)
+{
+ unsigned int x=0;
+ DListNode *pNode=NULL;
+ OOTimer *pTimer;
+ ooGkClientTimerCb *cbData=NULL;
+ RasCallAdmissionInfo *pAdmInfo = NULL;
+
+
+ for(x=0; x<pGkClient->callsAdmittedList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->callsAdmittedList, x);
+ pAdmInfo = (RasCallAdmissionInfo*)pNode->data;
+ if(pAdmInfo->call->callReference == call->callReference)
+ {
+ dListRemove(&pGkClient->callsAdmittedList, pNode);
+ memFreePtr(&pGkClient->ctxt, pAdmInfo);
+ memFreePtr(&pGkClient->ctxt, pNode);
+ return OO_OK;
+ }
+ }
+
+
+ for(x=0; x<pGkClient->timerList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->timerList, x);
+ pTimer = (OOTimer*)pNode->data;
+ cbData = (ooGkClientTimerCb*)pTimer->cbData;
+ if(cbData->timerType & OO_ARQ_TIMER &&
+ cbData->pAdmInfo->call->callReference == call->callReference)
+ {
+ memFreePtr(&pGkClient->ctxt, pTimer->cbData);
+ ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
+ break;
+ }
+ }
+
+ for(x=0; x<pGkClient->callsPendingList.count; x++)
+ {
+ pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
+ pAdmInfo = (RasCallAdmissionInfo*)pNode->data;
+ if(pAdmInfo->call->callReference == call->callReference)
+ {
+ dListRemove(&pGkClient->callsPendingList, pNode);
+ memFreePtr(&pGkClient->ctxt, pAdmInfo);
+ memFreePtr(&pGkClient->ctxt, pNode);
+ return OO_OK;
+ }
+ }
+
+ return OO_OK;
+}
+
+/*
+ * TODO: In case of GkErr, if GkMode is DiscoverGatekeeper,
+ * need to cleanup gkrouted calls, and discover another
+ * gatekeeper.
+ * Note: This function returns OO_FAILED, when we can not recover from
+ * the failure.
+ */
+int ooGkClientHandleClientOrGkFailure(ooGkClient *pGkClient)
+{
+ if(pGkClient->state == GkClientFailed)
+ {
+ OOTRACEERR1("Error: Internal Failure in GkClient. Closing "
+ "GkClient\n");
+ ooGkClientDestroy();
+ return OO_FAILED;
+ }
+ else if(pGkClient->state == GkClientGkErr) {
+ OOTRACEERR1("Error: Gatekeeper error. Either Gk not responding or "
+ "Gk sending invalid messages\n");
+ if(pGkClient->gkMode == RasUseSpecificGatekeeper)
+ {
+ OOTRACEERR1("Error: Gatekeeper error detected. Closing GkClient as "
+ "Gk mode is UseSpecifcGatekeeper\n");
+ ooGkClientDestroy();
+ return OO_FAILED;
+ }
+ else{
+ OOTRACEERR1("Error: Gatekeeper error detected. Closing GkClient. NEED"
+ " to implement recovery by rediscovering another gk\n");
+ ooGkClientDestroy();
+ return OO_FAILED;
+ }
+ }
+
+ return OO_FAILED;
+}
+
+/**
+ * TODO: This fuction might not work properly in case of additive registrations
+ * For example we registrered 10 aliases and gatekeeper accepted 8 of them.
+ * Now we want to register another two new aliases(not out of those first 10).
+ * Gk responds with RCF with empty terminalAlias field thus indicating both
+ * the aliases were accepted. If this function is called, it will even mark
+ * the earlier two unregistered aliases as registered. We will have to
+ * maintain a separete list of aliases being sent in RRQ for this.
+ */
+int ooGkClientUpdateRegisteredAliases
+ (ooGkClient *pGkClient, H225_SeqOfH225AliasAddress *pAddresses,
+ OOBOOL registered)
+{
+ int i=0, j, k;
+ DListNode* pNode=NULL;
+ ooAliases *pAlias=NULL;
+ H225AliasAddress *pAliasAddress=NULL;
+ H225TransportAddress *pTransportAddrss=NULL;
+ char value[MAXFILENAME];
+ OOBOOL bAdd = FALSE;
+
+ if(!pAddresses)
+ {
+ /* All aliases registered/unregistsred */
+ pAlias = gH323ep.aliases;
+
+ while(pAlias)
+ {
+ pAlias->registered = registered?TRUE:FALSE;
+ pAlias = pAlias->next;
+ }
+ return OO_OK;
+ }
+
+ /* Mark aliases as registered/unregistered*/
+ if(pAddresses->count<=0)
+ return OO_FAILED;
+
+ for(i=0; i<(int)pAddresses->count; i++)
+ {
+ pNode = dListFindByIndex (pAddresses, i);
+ if(!pNode)
+ {
+ OOTRACEERR1("Error:Invalid alias list passed to "
+ "ooGkClientUpdateRegisteredAliases\n");
+ continue;
+ }
+ pAliasAddress = (H225AliasAddress*)pNode->data;
+
+ if(!pAliasAddress){
+ OOTRACEERR1("Error:Invalid alias list passed to "
+ "ooGkClientUpdateRegisteredAliases\n");
+ continue;
+ }
+
+ switch(pAliasAddress->t)
+ {
+ case T_H225AliasAddress_dialedDigits:
+ pAlias = ooH323GetAliasFromList(gH323ep.aliases,
+ T_H225AliasAddress_dialedDigits,
+ (char*)pAliasAddress->u.dialedDigits);
+ if(pAlias)
+ {
+ pAlias->registered = registered?TRUE:FALSE;
+ }
+ else{
+ bAdd = registered?TRUE:FALSE;
+ }
+ break;
+ case T_H225AliasAddress_h323_ID:
+ for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars && (k<MAXFILENAME-1); j++)
+ {
+ if(pAliasAddress->u.h323_ID.data[j] < 256)
+ {
+ value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
+ }
+ }
+ value[k] = '\0';
+ pAlias = ooH323GetAliasFromList(gH323ep.aliases,
+ T_H225AliasAddress_h323_ID,
+ value);
+ if(pAlias)
+ {
+ pAlias->registered = registered?TRUE:FALSE;
+ }
+ else{
+ bAdd = registered?TRUE:FALSE;
+ }
+ break;
+ case T_H225AliasAddress_url_ID:
+ pAlias = ooH323GetAliasFromList(gH323ep.aliases,
+ T_H225AliasAddress_url_ID,
+ (char*)pAliasAddress->u.url_ID);
+ if(pAlias)
+ {
+ pAlias->registered = registered?TRUE:FALSE;
+ }
+ else{
+ bAdd = registered?TRUE:FALSE;
+ }
+ break;
+ case T_H225AliasAddress_transportID:
+ pTransportAddrss = pAliasAddress->u.transportID;
+ if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
+ {
+ OOTRACEERR1("Error:Alias transportID not IP address\n");
+ break;
+ }
+
+ sprintf(value, "%d.%d.%d.%d:%d",
+ pTransportAddrss->u.ipAddress->ip.data[0],
+ pTransportAddrss->u.ipAddress->ip.data[1],
+ pTransportAddrss->u.ipAddress->ip.data[2],
+ pTransportAddrss->u.ipAddress->ip.data[3],
+ pTransportAddrss->u.ipAddress->port);
+
+ pAlias = ooH323GetAliasFromList(gH323ep.aliases,
+ T_H225AliasAddress_transportID,
+ value);
+ if(pAlias)
+ {
+ pAlias->registered = registered?TRUE:FALSE;
+ }
+ else{
+ bAdd = registered?TRUE:FALSE;
+ }
+ break;
+ case T_H225AliasAddress_email_ID:
+ pAlias = ooH323GetAliasFromList(gH323ep.aliases,
+ T_H225AliasAddress_email_ID,
+ (char*) pAliasAddress->u.email_ID);
+ if(pAlias)
+ {
+ pAlias->registered = registered?TRUE:FALSE;
+ }
+ else{
+ bAdd = registered?TRUE:FALSE;
+ }
+ break;
+ default:
+ OOTRACEERR1("Error:Unhandled alias type found in registered "
+ "aliases\n");
+ }
+ if(bAdd)
+ {
+ pAlias = ooH323AddAliasToList(&gH323ep.aliases,
+ &gH323ep.ctxt, pAliasAddress);
+ if(pAlias){
+ pAlias->registered = registered?TRUE:FALSE;
+ }
+ else{
+ OOTRACEERR2("Warning:Could not add registered alias of "
+ "type %d to list.\n", pAliasAddress->t);
+ }
+ bAdd = FALSE;
+ }
+ pAlias = NULL;
+ }
+ return OO_OK;
+}