Add support change gatekeeper mode or ip per ooh323 reload command
[asterisk/asterisk.git] / addons / ooh323c / src / ooGkClient.c
index 534f220..c91b9ed 100644 (file)
@@ -20,8 +20,9 @@
  * This file contains functions to support RAS protocol. 
  *
  */
-#include <asterisk.h>
-#include <asterisk/lock.h>
+#include "asterisk.h"
+#include "asterisk/lock.h"
+#include "asterisk/netsock2.h"
 
 #include "ooGkClient.h"
 #include "ootypes.h"
@@ -169,23 +170,25 @@ void ooGkClientPrintConfig(ooGkClient *pGkClient)
 
 int ooGkClientDestroy(void)
 {
+   ooGkClient *pGkClient = gH323ep.gkClient;
+
    if(gH323ep.gkClient)
    {
-      if(gH323ep.gkClient->state == GkClientRegistered)
+      ast_mutex_lock(&pGkClient->Lock);
+      gH323ep.gkClient = NULL;
+      if(pGkClient->state == GkClientRegistered)
       {
          OOTRACEINFO1("Unregistering from Gatekeeper\n");
-         if(ooGkClientSendURQ(gH323ep.gkClient, NULL)!=OO_OK)
+         if(ooGkClientSendURQ(pGkClient, 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);
-      ast_mutex_lock(&gH323ep.gkClient->Lock);
-      ast_mutex_unlock(&gH323ep.gkClient->Lock);
-      ast_mutex_destroy(&gH323ep.gkClient->Lock);
-      memFreePtr(&gH323ep.ctxt, gH323ep.gkClient);
-      gH323ep.gkClient = NULL;
+      ooGkClientCloseChannel(pGkClient);
+      freeContext(&pGkClient->msgCtxt);
+      freeContext(&pGkClient->ctxt);
+      ast_mutex_unlock(&pGkClient->Lock);
+      ast_mutex_destroy(&pGkClient->Lock);
+      memFreePtr(&gH323ep.ctxt, pGkClient);
    }
    return OO_OK;
 }
@@ -261,7 +264,7 @@ int ooGkClientCreateChannel(ooGkClient *pGkClient)
    int ret=0;
    OOIPADDR ipaddrs;
    /* Create socket */
-   if((ret=ooSocketCreateUDP(&pGkClient->rasSocket))!=ASN_OK)
+   if((ret=ooSocketCreateUDP(&pGkClient->rasSocket, 4))!=ASN_OK)
    {
       OOTRACEERR1("Failed to create RAS socket\n");
       pGkClient->state = GkClientFailed;
@@ -269,7 +272,7 @@ int ooGkClientCreateChannel(ooGkClient *pGkClient)
    }
    if(pGkClient->localRASPort)
    {
-      ret= ooSocketStrToAddr (pGkClient->localRASIP, &ipaddrs);
+      inet_pton(AF_INET, pGkClient->localRASIP, &ipaddrs);
       if( (ret=ooSocketBind( pGkClient->rasSocket, ipaddrs, 
            pGkClient->localRASPort))!=ASN_OK ) 
       {
@@ -295,7 +298,7 @@ int ooGkClientCreateChannel(ooGkClient *pGkClient)
       OOTRACEDBGA1("Determining ip address for RAS channel "
                    "multihomed mode. \n");
       ret = ooSocketGetIpAndPort(pGkClient->rasSocket, pGkClient->localRASIP, 
-                                 20, &pGkClient->localRASPort);
+                                 20, &pGkClient->localRASPort, NULL);
       if(ret != ASN_OK)
       {
          OOTRACEERR1("Error:Failed to retrieve local ip and port from "
@@ -364,7 +367,7 @@ void ooGkClientFillVendor
 
 int ooGkClientReceive(ooGkClient *pGkClient)
 {
-   ASN1OCTET recvBuf[1024];
+   ASN1OCTET recvBuf[ASN_K_ENCBUFSIZ];
    int recvLen;
    char remoteHost[32];
    int iFromPort=0;
@@ -375,7 +378,7 @@ int ooGkClientReceive(ooGkClient *pGkClient)
    ast_mutex_lock(&pGkClient->Lock);
    pctxt = &pGkClient->msgCtxt;
 
-   recvLen = ooSocketRecvFrom(pGkClient->rasSocket, recvBuf, 1024, remoteHost,
+   recvLen = ooSocketRecvFrom(pGkClient->rasSocket, recvBuf, 2048, remoteHost,
                               32, &iFromPort);
    if(recvLen <0)
    {
@@ -430,7 +433,7 @@ int ooGkClientReceive(ooGkClient *pGkClient)
       if(iRet != OO_OK)
       {
          OOTRACEERR1("Error: Failed to handle received RAS message\n");
-         //pGkClient->state = GkClientFailed;
+         pGkClient->state = GkClientFailed;
       }
       memReset(pctxt);
    }
@@ -666,7 +669,7 @@ int ooGkClientSendGRQ(ooGkClient *pGkClient)
    }
 
  
-   ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pRasAddress->ip.data);
+   inet_pton(AF_INET, pGkClient->localRASIP, pRasAddress->ip.data);
 
    pRasAddress->ip.numocts = 4;
    pRasAddress->port = pGkClient->localRASPort;
@@ -686,7 +689,7 @@ int ooGkClientSendGRQ(ooGkClient *pGkClient)
 
    pGkReq->m.endpointAliasPresent=TRUE;
    if(OO_OK != ooPopulateAliasList(&pGkClient->msgCtxt, gH323ep.aliases, 
-                                      &pGkReq->endpointAlias))
+                                      &pGkReq->endpointAlias, 0))
    {
       OOTRACEERR1("Error Failed to fill alias information for GRQ message\n");
       memReset(&pGkClient->msgCtxt);
@@ -823,10 +826,9 @@ int ooGkClientHandleGatekeeperConfirm
              sizeof(ASN116BITCHAR)* pGkClient->gkId.nchars);
    }
    else{
-      OOTRACEERR1("ERROR:No Gatekeeper ID present in received GKConfirmed "
+      OOTRACEINFO1("ERROR:No Gatekeeper ID present in received GKConfirmed "
                   "message\n");
-      OOTRACEINFO1("Ignoring message and will retransmit GRQ after timeout\n");
-      return OO_FAILED;
+      pGkClient->gkId.nchars = 0;
    }
    
    /* Extract Gatekeeper's RAS address */
@@ -859,7 +861,6 @@ int ooGkClientHandleGatekeeperConfirm
          memFreePtr(&pGkClient->ctxt, pTimer->cbData);
          ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
          OOTRACEDBGA1("Deleted GRQ Timer.\n");
-         break;
       }
    }
 
@@ -933,7 +934,7 @@ int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive)
    }
    pTransportAddress->t = T_H225TransportAddress_ipAddress;
    pTransportAddress->u.ipAddress = pIpAddress;
-   ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddress->ip.data);
+   inet_pton(AF_INET, pGkClient->localRASIP, pIpAddress->ip.data);
    pIpAddress->ip.numocts = 4;
    pIpAddress->port = gH323ep.listenPort;
    
@@ -961,7 +962,7 @@ int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive)
    pTransportAddress->t = T_H225TransportAddress_ipAddress;
    pTransportAddress->u.ipAddress = pIpAddress;
    
-   ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddress->ip.data);
+   inet_pton(AF_INET, pGkClient->localRASIP, pIpAddress->ip.data);
 
    pIpAddress->ip.numocts = 4;
    pIpAddress->port = pGkClient->localRASPort;
@@ -1010,7 +1011,7 @@ int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive)
 
    pRegReq->m.terminalAliasPresent=TRUE;
    if(OO_OK != ooPopulateAliasList(pctxt, gH323ep.aliases, 
-                                     &pRegReq->terminalAlias)) {
+                                     &pRegReq->terminalAlias, 0)) {
      OOTRACEERR1("Error filling alias for RRQ\n");
      memReset(pctxt); 
      pGkClient->state = GkClientFailed;
@@ -1018,21 +1019,23 @@ int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive)
      return OO_FAILED;
    }
    
-   pRegReq->m.gatekeeperIdentifierPresent=TRUE;
-   pRegReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
-   pRegReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc
+   if (pGkClient->gkId.nchars) {
+    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)
-   {
+    if(!pRegReq->gatekeeperIdentifier.data)
+    {
       OOTRACEERR1("Error: Failed to allocate memory for GKIdentifier in RRQ "
                    "message.\n");
       memReset(pctxt);
       pGkClient->state = GkClientFailed;
       ast_mutex_unlock(&pGkClient->Lock);
       return OO_FAILED;
-   }
-   memcpy(pRegReq->gatekeeperIdentifier.data, pGkClient->gkId.data, 
+    }
+    memcpy(pRegReq->gatekeeperIdentifier.data, pGkClient->gkId.data, 
                                 pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
+   }
    
    ooGkClientFillVendor(pGkClient, &pRegReq->endpointVendor);
    
@@ -1062,7 +1065,7 @@ int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive)
          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));
+           (ASN116BITCHAR*)memAlloc(pctxt, pGkClient->endpointId.nchars*sizeof(ASN116BITCHAR));
       if (pRegReq->endpointIdentifier.data) {
          pRegReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
          pRegReq->m.endpointIdentifierPresent = TRUE;
@@ -1135,6 +1138,8 @@ int ooGkClientHandleRegistrationConfirm
    ooGkClientTimerCb *cbData;
    ASN1UINT regTTL=0;
    /* Extract Endpoint Id */
+   if (pGkClient->endpointId.data)
+       memFreePtr(&pGkClient->ctxt, pGkClient->endpointId.data);
    pGkClient->endpointId.nchars = 
                               pRegistrationConfirm->endpointIdentifier.nchars;
    pGkClient->endpointId.data = (ASN116BITCHAR*)memAlloc(&pGkClient->ctxt,
@@ -1149,7 +1154,26 @@ int ooGkClientHandleRegistrationConfirm
    memcpy(pGkClient->endpointId.data, 
           pRegistrationConfirm->endpointIdentifier.data,
           sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
+
+   /* Extract GK Identifier */
    
+   if(pRegistrationConfirm->m.gatekeeperIdentifierPresent && pGkClient->gkId.nchars == 0)
+   {
+      pGkClient->gkId.nchars = pRegistrationConfirm->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, 
+             pRegistrationConfirm->gatekeeperIdentifier.data,
+             sizeof(ASN116BITCHAR)* pGkClient->gkId.nchars);
+   }
+
    /* Extract CallSignalling Address */
    for(i=0; i<(int)pRegistrationConfirm->callSignalAddress.count; i++)
    {
@@ -1190,8 +1214,11 @@ int ooGkClientHandleRegistrationConfirm
 
       if(pGkClient->regTimeout > DEFAULT_TTL_OFFSET)
          regTTL = pGkClient->regTimeout - DEFAULT_TTL_OFFSET;
-      else
-         regTTL = pGkClient->regTimeout;
+      else {
+         regTTL = pGkClient->regTimeout - 1; /* -1 due to some ops expire us few earlier */
+        if (regTTL <= 0)
+               regTTL = 1;
+      }
 
       cbData = (ooGkClientTimerCb*) memAlloc
                                 (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
@@ -1239,7 +1266,6 @@ int ooGkClientHandleRegistrationConfirm
          memFreePtr(&pGkClient->ctxt, pTimer->cbData);
          ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
          OOTRACEDBGA1("Deleted RRQ Timer.\n");
-         break;
       }
    }
    pGkClient->state = GkClientRegistered;
@@ -1266,7 +1292,6 @@ int ooGkClientHandleRegistrationReject
          memFreePtr(&pGkClient->ctxt, pTimer->cbData);
          ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
          OOTRACEDBGA1("Deleted RRQ Timer.\n");
-         break;
       }
    }
 
@@ -1410,7 +1435,7 @@ int ooGkClientSendURQ(ooGkClient *pGkClient, ooAliases *aliases)
    }
    pTransportAddress->t = T_H225TransportAddress_ipAddress;
    pTransportAddress->u.ipAddress = pIpAddress;
-   ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddress->ip.data);
+   inet_pton(AF_INET, pGkClient->localRASIP, pIpAddress->ip.data);
    pIpAddress->ip.numocts = 4;
    pIpAddress->port = gH323ep.listenPort;
    
@@ -1437,27 +1462,29 @@ int ooGkClientSendURQ(ooGkClient *pGkClient, ooAliases *aliases)
           sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
 
    /* Populate gatekeeper identifier */
-   pUnregReq->m.gatekeeperIdentifierPresent = TRUE;
-   pUnregReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
-   pUnregReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
+   if (pGkClient->gkId.nchars) {
+    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)
-   {
+    if(!pUnregReq->gatekeeperIdentifier.data)
+    {
       OOTRACEERR1("Error:Failed to allocate memory for GKID of URQ message\n");
       memReset(pctxt);
       pGkClient->state = GkClientFailed;
       ast_mutex_unlock(&pGkClient->Lock);
       return OO_FAILED;
-   }
-   memcpy((void*)pUnregReq->gatekeeperIdentifier.data, 
+    }
+    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);
+      ooPopulateAliasList(pctxt, aliases, &pUnregReq->endpointAlias, 0);
    }
 
   
@@ -1482,8 +1509,10 @@ int ooGkClientSendURQ(ooGkClient *pGkClient, ooAliases *aliases)
 int ooGkClientHandleUnregistrationRequest
    (ooGkClient *pGkClient, H225UnregistrationRequest * punregistrationRequest)
 {
-   int iRet=0;
-
+   int iRet=0, x;
+   OOTimer *pTimer = NULL;
+   DListNode *pNode = NULL;
    /* Lets first send unregistration confirm message back to gatekeeper*/
    ooGkClientSendUnregistrationConfirm(pGkClient, 
                                       punregistrationRequest->requestSeqNum);
@@ -1505,6 +1534,24 @@ int ooGkClientHandleUnregistrationRequest
       pGkClient->rrqRetries = 0;
       pGkClient->state = GkClientDiscovered;
 
+
+      /* delete the corresponding RRQ & REG timers */
+       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");
+               }
+               if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_REG_TIMER) {
+                       memFreePtr(&pGkClient->ctxt, pTimer->cbData);
+                       ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
+                       OOTRACEDBGA1("Deleted REG Timer.\n");
+               }
+       }
+
       iRet = ooGkClientSendRRQ(pGkClient, 0); 
       if(iRet != OO_OK)
       {
@@ -1623,14 +1670,14 @@ int ooGkClientSendAdmissionRequest
       ast_mutex_unlock(&pGkClient->Lock);
       return OO_FAILED;
    }
-   ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddressLocal->ip.data);
+   inet_pton(AF_INET, pGkClient->localRASIP, pIpAddressLocal->ip.data);
 
    pIpAddressLocal->ip.numocts = 4;
    pIpAddressLocal->port = gH323ep.listenPort;
 
    if(!ooUtilsIsStrEmpty(call->remoteIP))
    {
-      ooSocketConvertIpToNwAddr(call->remoteIP, pIpAddressRemote->ip.data);
+      inet_pton(AF_INET, call->remoteIP, pIpAddressRemote->ip.data);
       pIpAddressRemote->ip.numocts = 4;
       pIpAddressRemote->port = call->remotePort;
    }
@@ -1716,7 +1763,7 @@ int ooGkClientSendAdmissionRequest
    {
       pAdmReq->m.destinationInfoPresent = 1;
       if(OO_OK != ooPopulateAliasList(&pGkClient->msgCtxt, destAliases,
-                                      &pAdmReq->destinationInfo))
+                      &pAdmReq->destinationInfo, T_H225AliasAddress_dialedDigits))
       {
          OOTRACEERR1("Error:Failed to populate destination aliases - "
                     "ARQ message\n");
@@ -1731,7 +1778,7 @@ int ooGkClientSendAdmissionRequest
    if(srcAliases)
    {
       iRet = ooPopulateAliasList(&pGkClient->msgCtxt, srcAliases,
-                                                          &pAdmReq->srcInfo);
+                              &pAdmReq->srcInfo, 0);
       if(OO_OK != iRet)
       {
          OOTRACEERR1("Error:Failed to populate source aliases -ARQ message\n");
@@ -1766,21 +1813,23 @@ int ooGkClientSendAdmissionRequest
                                              sizeof(H225CallIdentifier));
 
    /* Populate Gatekeeper Id */
-   pAdmReq->m.gatekeeperIdentifierPresent = TRUE;
-   pAdmReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
-   pAdmReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
+   if (pGkClient->gkId.nchars) {
+    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)
-   {
+    if(!pAdmReq->gatekeeperIdentifier.data)
+    {
       OOTRACEERR1("Error:Failed to allocate memory for GKID of ARQ message\n");
       memReset(pctxt);
       pGkClient->state = GkClientFailed;
       ast_mutex_unlock(&pGkClient->Lock);
       return OO_FAILED;
-   }
-   memcpy((void*)pAdmReq->gatekeeperIdentifier.data, 
+    }
+    memcpy((void*)pAdmReq->gatekeeperIdentifier.data, 
           (void*)pGkClient->gkId.data, 
           sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
+   }
 
    pAdmReq->m.willSupplyUUIEsPresent = 1;
    pAdmReq->willSupplyUUIEs = FALSE;
@@ -1874,6 +1923,8 @@ int ooGkClientHandleAdmissionConfirm
    OOTimer *pTimer = NULL;
    char ip[20];
 
+   ast_mutex_lock(&pGkClient->Lock);
+
    /* Search call in pending calls list */
    for(x=0 ; x<pGkClient->callsPendingList.count; x++)
    {
@@ -1884,6 +1935,9 @@ int ooGkClientHandleAdmissionConfirm
          OOTRACEDBGC3("Found Pending call(%s, %s)\n", 
                       pCallAdmInfo->call->callType, 
                       pCallAdmInfo->call->callToken);
+
+         ast_mutex_lock(&pCallAdmInfo->call->GkLock);
+
          /* Populate Remote IP */
          if(pAdmissionConfirm->destCallSignalAddress.t != 
                                       T_H225TransportAddress_ipAddress)
@@ -1892,6 +1946,9 @@ int ooGkClientHandleAdmissionConfirm
                         "Gatekeeper is not an IPv4 address\n");
             OOTRACEINFO1("Ignoring ACF, will wait for timeout and retransmit "
                          "ARQ\n");
+            ast_mutex_unlock(&pCallAdmInfo->call->GkLock);
+            ast_mutex_unlock(&pGkClient->Lock);
+            ast_cond_signal(&pCallAdmInfo->call->gkWait);
             return OO_FAILED;
          }
          ipAddress = pAdmissionConfirm->destCallSignalAddress.u.ipAddress;
@@ -1900,8 +1957,11 @@ int ooGkClientHandleAdmissionConfirm
                                     ipAddress->ip.data[1],
                                     ipAddress->ip.data[2],
                                     ipAddress->ip.data[3]);
-         if(strcmp(ip, "0.0.0.0"))
+         if(strcmp(ip, "0.0.0.0")) {
+/* fix this when gk client will adopt to work with IPv6 */
+           pCallAdmInfo->call->versionIP = 4;
             strcpy(pCallAdmInfo->call->remoteIP, ip);
+        }
          pCallAdmInfo->call->remotePort = ipAddress->port;
          /* Update call model */
          if(pAdmissionConfirm->callModel.t == T_H225CallModel_direct)
@@ -1950,15 +2010,15 @@ int ooGkClientHandleAdmissionConfirm
                        pCallAdmInfo->call->callToken);
 
         pCallAdmInfo->call->callState = OO_CALL_CONNECTING;
-        ast_cond_signal(&pCallAdmInfo->call->gkWait);
-         /* ooH323CallAdmitted( pCallAdmInfo->call); */
 
          dListRemove(&pGkClient->callsPendingList, pNode);
          dListAppend(&pGkClient->ctxt, &pGkClient->callsAdmittedList, 
                                                         pNode->data);
          memFreePtr(&pGkClient->ctxt, pNode);
+         ast_mutex_unlock(&pCallAdmInfo->call->GkLock);
+        ast_mutex_unlock(&pGkClient->Lock);
+        ast_cond_signal(&pCallAdmInfo->call->gkWait);
          return OO_OK;
-         break;
       }
       else
       {
@@ -1967,6 +2027,7 @@ int ooGkClientHandleAdmissionConfirm
    }
    OOTRACEERR1("Error: Failed to process ACF as there is no corresponding "
                "pending call\n");
+   ast_mutex_unlock(&pGkClient->Lock);
    return OO_OK;
 }
 
@@ -1980,6 +2041,8 @@ int ooGkClientHandleAdmissionReject
    OOH323CallData *call=NULL;
    OOTimer *pTimer = NULL;
 
+   ast_mutex_lock(&pGkClient->Lock);
+
    /* Search call in pending calls list */
    for(x=0 ; x<pGkClient->callsPendingList.count; x++)
    {
@@ -1996,6 +2059,7 @@ int ooGkClientHandleAdmissionReject
       OOTRACEWARN2("Received admission reject with request number %d can not"
                    " be matched with any pending call.\n", 
                    pAdmissionReject->requestSeqNum);
+      ast_mutex_unlock(&pGkClient->Lock);
       return OO_OK;
    }
    else{
@@ -2004,6 +2068,7 @@ int ooGkClientHandleAdmissionReject
       memFreePtr(&pGkClient->ctxt, pCallAdmInfo);
       memFreePtr(&pGkClient->ctxt, pNode);
    }
+   ast_mutex_lock(&pCallAdmInfo->call->GkLock);
 
    /* Delete ARQ timer */
    for(y=0; y<pGkClient->timerList.count; y++)
@@ -2027,7 +2092,7 @@ int ooGkClientHandleAdmissionReject
                 "(%s, %s)\n", pAdmissionReject->rejectReason.t, call->callType,
                  call->callToken);
    
-   call->callState = OO_CALL_CLEAR;
+   call->callState = OO_CALL_CLEARED;
 
    switch(pAdmissionReject->rejectReason.t)
    {
@@ -2068,6 +2133,8 @@ int ooGkClientHandleAdmissionReject
          break;
    }
 
+   ast_mutex_unlock(&pCallAdmInfo->call->GkLock);
+   ast_mutex_unlock(&pGkClient->Lock);
    ast_cond_signal(&pCallAdmInfo->call->gkWait);
    return OO_OK;   
 }
@@ -2129,7 +2196,7 @@ int ooGkClientSendIRR
       ast_mutex_unlock(&pGkClient->Lock);
       return OO_FAILED;
    }
-   ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpAddressLocal->ip.data);
+   inet_pton(AF_INET, pGkClient->localRASIP, pIpAddressLocal->ip.data);
 
    pIpAddressLocal->ip.numocts = 4;
    pIpAddressLocal->port = gH323ep.listenPort;
@@ -2160,7 +2227,7 @@ int ooGkClientSendIRR
 
    pIpRasAddress->ip.numocts = 4;
    pIpRasAddress->port = pGkClient->localRASPort;
-   ooSocketConvertIpToNwAddr(pGkClient->localRASIP, pIpRasAddress->ip.data);
+   inet_pton(AF_INET, pGkClient->localRASIP, pIpRasAddress->ip.data);
 
    pIRR->rasAddress.u.ipAddress = pIpRasAddress;
    pIRR->rasAddress.t=T_H225TransportAddress_ipAddress; /* IPv4 address */
@@ -2204,10 +2271,10 @@ int ooGkClientSendIRR
    if(srcAliases)
    {
       iRet = ooPopulateAliasList(&pGkClient->msgCtxt, srcAliases,
-                                                          &pIRR->endpointAlias);
+                             &pIRR->endpointAlias, T_H225AliasAddress_h323_ID);
       if(OO_OK != iRet)
       {
-         OOTRACEERR1("Error:Failed to populate source aliases -ARQ message\n");
+         OOTRACEERR1("Error:Failed to populate source aliases -IRR message\n");
          memReset(pctxt);
          pGkClient->state = GkClientFailed;
         ast_mutex_unlock(&pGkClient->Lock);
@@ -2259,11 +2326,11 @@ int ooGkClientSendIRR
       return OO_FAILED;
    }
    pLocalAddr->ip.numocts = 4;
-   ooSocketConvertIpToNwAddr(call->localIP, pLocalAddr->ip.data);
+   inet_pton(AF_INET, call->localIP, pLocalAddr->ip.data);
    pLocalAddr->port = (call->pH225Channel->port) ? call->pH225Channel->port : gH323ep.listenPort;
 
    pRemoteAddr->ip.numocts = 4;
-   ooSocketConvertIpToNwAddr(call->remoteIP, pRemoteAddr->ip.data);
+   inet_pton(AF_INET, call->remoteIP, pRemoteAddr->ip.data);
    pRemoteAddr->port = call->remotePort;
 
    perCallInfo->callSignaling.m.sendAddressPresent = TRUE;
@@ -2416,20 +2483,22 @@ int ooGkClientSendDisengageRequest(ooGkClient *pGkClient, OOH323CallData *call)
    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
+   if (pGkClient->gkId.nchars) {
+    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)
-   {
+    if(!pDRQ->gatekeeperIdentifier.data)
+    {
       OOTRACEERR1("Error:Failed to allocate memory for GKId in DRQ.\n");
       memReset(pctxt);
       pGkClient->state = GkClientFailed;
       ast_mutex_unlock(&pGkClient->Lock);
       return OO_FAILED;
-   }
-   memcpy(pDRQ->gatekeeperIdentifier.data, pGkClient->gkId.data, 
+    }
+    memcpy(pDRQ->gatekeeperIdentifier.data, pGkClient->gkId.data, 
                                 pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
+   }
 
    pDRQ->m.terminationCausePresent = 1;
    pDRQ->terminationCause.t = T_H225CallTerminationCause_releaseCompleteCauseIE;
@@ -2521,7 +2590,43 @@ int ooGkClientRRQTimerExpired(void*pdata)
    }
    memFreePtr(&pGkClient->ctxt, cbData);
    OOTRACEERR1("Error:Failed to register with gatekeeper\n");
-   pGkClient->state = GkClientGkErr;
+   pGkClient->state = GkClientUnregistered;
+
+
+/* Create timer to re-register after default timeout */
+/* network failure is one of cases here */
+
+   ast_mutex_lock(&pGkClient->Lock);
+
+   cbData = (ooGkClientTimerCb*) memAlloc
+                               (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
+   if(!cbData)
+   {
+      OOTRACEERR1("Error:Failed to allocate memory to RRQ timer callback\n");
+      pGkClient->state = GkClientFailed;
+      ast_mutex_unlock(&pGkClient->Lock);
+      return OO_FAILED;
+   }
+
+
+   cbData->timerType = OO_RRQ_TIMER;
+   cbData->pGkClient = pGkClient;
+   if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
+                     &ooGkClientRRQTimerExpired, pGkClient->regTimeout,
+                     cbData, FALSE))
+   {
+      OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
+      memFreePtr(&pGkClient->ctxt, cbData);
+      pGkClient->state = GkClientFailed;
+      ast_mutex_unlock(&pGkClient->Lock);
+      return OO_FAILED;
+   }
+
+/* clear rrq count for re-register after regTimeout */
+   pGkClient->rrqRetries = 0;
+
+   ast_mutex_unlock(&pGkClient->Lock);
+
    return OO_FAILED;
 }
 
@@ -2549,7 +2654,37 @@ int ooGkClientGRQTimerExpired(void* pdata)
    }
 
    OOTRACEERR1("Error:Gatekeeper could not be found\n");
-   pGkClient->state = GkClientGkErr;
+   pGkClient->state = GkClientUnregistered;
+/* setup timer to re-send grq after timeout */
+
+   ast_mutex_lock(&pGkClient->Lock);
+   cbData = (ooGkClientTimerCb*) memAlloc
+                               (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
+   if(!cbData)
+   {
+      OOTRACEERR1("Error:Failed to allocate memory to GRQ timer callback\n");
+      pGkClient->state = GkClientFailed;
+      ast_mutex_unlock(&pGkClient->Lock);
+      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;
+      ast_mutex_unlock(&pGkClient->Lock);
+      return OO_FAILED;
+   }
+/* clear grq counter */
+
+   pGkClient->grqRetries = 0;
+   ast_mutex_unlock(&pGkClient->Lock);
+
    return OO_FAILED;
 }