Send re-register packets by GRQ (gatekeeper request) interval
[asterisk/asterisk.git] / addons / ooh323c / src / ooGkClient.c
1 /*
2  * Copyright (C) 2005 by Page Iberica, S.A.
3  * Copyright (C) 2005 by Objective Systems, Inc.
4  *
5  * This software is furnished under an open source license and may be 
6  * used and copied only in accordance with the terms of this license. 
7  * The text of the license may generally be found in the root 
8  * directory of this installation in the COPYING file.  It 
9  * can also be viewed online at the following URL:
10  *
11  *   http://www.obj-sys.com/open/license.html
12  *
13  * Any redistributions of this file including modified versions must 
14  * maintain this copyright notice.
15  *
16  *****************************************************************************/
17
18 /**
19  * @file ooGkClient.c 
20  * This file contains functions to support RAS protocol. 
21  *
22  */
23 #include "asterisk.h"
24 #include "asterisk/lock.h"
25 #include "asterisk/netsock2.h"
26
27 #include "ooGkClient.h"
28 #include "ootypes.h"
29 #include "ootrace.h"
30 #include "ooports.h"
31 #include "ooasn1.h"
32 #include "oochannels.h"
33 #include "printHandler.h"
34 #include "ooCalls.h"
35 #include "H323-MESSAGES.h"
36 #include "ooDateTime.h"
37 #include "ooq931.h"
38 #include "ooh323.h"
39 #include "ooh323ep.h"
40 #include "ooTimer.h"
41 #include "ooSocket.h"
42 #include "ooUtils.h"
43
44 /** Global endpoint structure */
45 extern OOH323EndPoint gH323ep;
46
47 static ASN1OBJID gProtocolID = {
48    6, { 0, 0, 8, 2250, 0, 4 }
49 };
50
51 int ooGkClientInit(enum RasGatekeeperMode eGkMode,
52               char *szGkAddr, int iGkPort )
53 {
54    ooGkClient *pGkClient=NULL;
55    OOInterface *cur=NULL;
56    pGkClient = (ooGkClient*)
57                          memAlloc(&gH323ep.ctxt, sizeof(ooGkClient));
58    if(!pGkClient)
59    {
60       OOTRACEERR1("Error: Failed to allocate memory to Gatekeeper Client.\n");
61       return OO_FAILED;
62    }
63  
64    memset(pGkClient, 0, sizeof(ooGkClient));
65    ast_mutex_init(&pGkClient->Lock);
66    gH323ep.gkClient = pGkClient;
67    initContext(&(pGkClient->ctxt));
68    initContext(&(pGkClient->msgCtxt));
69    pGkClient->rrqRetries = 0;
70    pGkClient->grqRetries = 0;
71
72    strcpy(pGkClient->localRASIP, gH323ep.signallingIP);
73 #ifndef _WIN32
74    if(!strcmp(pGkClient->localRASIP, "0.0.0.0") ||
75       !strcmp(pGkClient->localRASIP, "127.0.0.1"))
76    {
77       if(!gH323ep.ifList)
78       {
79          if(ooSocketGetInterfaceList(&gH323ep.ctxt, &gH323ep.ifList)!= ASN_OK)
80          {
81             OOTRACEERR1("Error:Failed to retrieve interface addresses\n");
82             return OO_FAILED;
83          }
84       }
85       for(cur = gH323ep.ifList; cur; cur = cur->next)
86       {
87          if(!strcmp(cur->name, "lo") || !strcmp(cur->addr, "127.0.0.1"))
88             continue;
89          break;
90       }
91       if(cur)
92       {
93          OOTRACEINFO2("Using local RAS Ip address %s\n", cur->addr);
94          strcpy(pGkClient->localRASIP, cur->addr);
95       }
96       else{
97          OOTRACEERR1("Error:Failed to assign a local RAS IP address\n");
98          return OO_FAILED;
99       }
100    }
101 #endif   
102    if(OO_OK != ooGkClientSetGkMode(pGkClient, eGkMode, szGkAddr, iGkPort))
103    {
104       OOTRACEERR1("Error:Failed to set Gk mode\n");
105       memReset(&gH323ep.ctxt);
106       return OO_FAILED;
107    }
108   
109    /* Create default parameter set */
110    pGkClient->grqTimeout = DEFAULT_GRQ_TIMEOUT;
111    pGkClient->rrqTimeout = DEFAULT_RRQ_TIMEOUT;
112    pGkClient->regTimeout = DEFAULT_REG_TTL;
113    pGkClient->arqTimeout = DEFAULT_ARQ_TIMEOUT;
114    pGkClient->drqTimeout = DEFAULT_DRQ_TIMEOUT;
115    dListInit(&pGkClient->callsPendingList);
116    dListInit(&pGkClient->callsAdmittedList);
117    dListInit(&pGkClient->timerList);
118    pGkClient->state = GkClientIdle;
119    return OO_OK;
120 }
121
122
123 int ooGkClientSetCallbacks
124    (ooGkClient *pGkClient, OOGKCLIENTCALLBACKS callbacks)
125 {
126    pGkClient->callbacks.onReceivedRegistrationConfirm = 
127                                       callbacks.onReceivedRegistrationConfirm;
128    pGkClient->callbacks.onReceivedUnregistrationConfirm = 
129                                      callbacks.onReceivedUnregistrationConfirm;
130    pGkClient->callbacks.onReceivedUnregistrationRequest = 
131                                      callbacks.onReceivedUnregistrationRequest;
132    return OO_OK;
133 }
134
135 int ooGkClientReInit(ooGkClient *pGkClient)
136 {
137
138    ooGkClientCloseChannel(pGkClient);
139    pGkClient->gkRasIP[0]='\0';
140    pGkClient->gkCallSignallingIP[0]='\0';
141    pGkClient->gkRasPort = 0;
142    pGkClient->gkCallSignallingPort = 0;
143    pGkClient->rrqRetries = 0;
144    pGkClient->grqRetries = 0;
145    pGkClient->requestSeqNum = 0;
146    
147    dListFreeAll(&pGkClient->ctxt, &pGkClient->callsPendingList);
148    dListFreeAll(&pGkClient->ctxt, &pGkClient->callsAdmittedList);
149    dListFreeAll(&pGkClient->ctxt, &pGkClient->timerList);
150    pGkClient->state = GkClientIdle;
151    return OO_OK;
152 }
153
154 void ooGkClientPrintConfig(ooGkClient *pGkClient)
155 {
156    OOTRACEINFO1("Gatekeeper Client Configuration:\n");
157    if(pGkClient->gkMode == RasUseSpecificGatekeeper)
158    {
159       OOTRACEINFO1("\tGatekeeper mode - UseSpecificGatekeeper\n");
160       OOTRACEINFO3("\tGatekeeper To Use - %s:%d\n", pGkClient->gkRasIP, 
161                                                     pGkClient->gkRasPort);
162    }
163    else if(pGkClient->gkMode == RasDiscoverGatekeeper) {
164       OOTRACEINFO1("\tGatekeeper mode - RasDiscoverGatekeeper\n");
165    }
166    else {
167       OOTRACEERR1("Invalid GatekeeperMode\n");
168    }
169 }
170
171 int ooGkClientDestroy(void)
172 {
173    ooGkClient *pGkClient = gH323ep.gkClient;
174
175    if(gH323ep.gkClient)
176    {
177       ast_mutex_lock(&pGkClient->Lock);
178       gH323ep.gkClient = NULL;
179       if(pGkClient->state == GkClientRegistered)
180       {
181          OOTRACEINFO1("Unregistering from Gatekeeper\n");
182          if(ooGkClientSendURQ(pGkClient, NULL)!=OO_OK)
183             OOTRACEERR1("Error:Failed to send URQ to gatekeeper\n");
184       }
185       OOTRACEINFO1("Destroying Gatekeeper Client\n");
186       ooGkClientCloseChannel(pGkClient);
187       freeContext(&pGkClient->msgCtxt);
188       freeContext(&pGkClient->ctxt);
189       ast_mutex_unlock(&pGkClient->Lock);
190       ast_mutex_destroy(&pGkClient->Lock);
191       memFreePtr(&gH323ep.ctxt, pGkClient);
192    }
193    return OO_OK;
194 }
195
196 int ooGkClientStart(ooGkClient *pGkClient)
197 {
198    int iRet=0;
199    iRet = ooGkClientCreateChannel(pGkClient);
200
201    if(iRet != OO_OK)
202    {
203       OOTRACEERR1("Error: GkClient Channel Creation failed\n");
204       return OO_FAILED;
205    }
206    
207    ast_mutex_lock(&pGkClient->Lock);
208    pGkClient->discoveryComplete = FALSE;
209    iRet = ooGkClientSendGRQ(pGkClient);
210    if(iRet != OO_OK)
211    {
212       OOTRACEERR1("Error:Failed to send GRQ message\n");
213       pGkClient->state = GkClientFailed;
214       ast_mutex_unlock(&pGkClient->Lock);
215       return OO_FAILED;
216    }
217    ast_mutex_unlock(&pGkClient->Lock);
218    return OO_OK;
219 }
220    
221
222 int ooGkClientSetGkMode(ooGkClient *pGkClient, enum RasGatekeeperMode eGkMode, 
223                         char *szGkAddr, int iGkPort )
224 {
225    pGkClient->gkMode = eGkMode;
226    if(eGkMode == RasUseSpecificGatekeeper)
227    {
228       OOTRACEINFO1("Gatekeeper Mode - RasUseSpecificGatekeeper\n");
229       if(szGkAddr)
230       {
231          if(strlen(szGkAddr)>MAX_IP_LEN)
232          { 
233             OOTRACEERR2("Error:Invalid IP address specified - %s\n", szGkAddr);
234             return OO_FAILED;
235          }
236          strcpy(pGkClient->gkRasIP, szGkAddr);
237       }
238       if(iGkPort)
239          pGkClient->gkRasPort = iGkPort;
240       else
241          pGkClient->gkRasPort = DEFAULT_GKPORT;
242
243       OOTRACEINFO3("Gatekeeper IP:port set to - %s:%d\n", 
244                     szGkAddr,  pGkClient->gkRasPort);
245    }
246    else if(eGkMode == RasDiscoverGatekeeper) {
247       OOTRACEINFO1("Gatekeeper Mode - RasDiscoverGatekeeper\n");
248    }
249    else if(eGkMode == RasNoGatekeeper) {
250       OOTRACEINFO1("Gatekeeper Mode - RasNoGatekeeper\n");
251    }
252
253    return OO_OK;
254 }
255
256    
257 /**
258  * Create the RAS channel (socket).
259  *
260  */
261
262 int ooGkClientCreateChannel(ooGkClient *pGkClient)
263 {
264    int ret=0;
265    OOIPADDR ipaddrs;
266    /* Create socket */
267    if((ret=ooSocketCreateUDP(&pGkClient->rasSocket, 4))!=ASN_OK)
268    {
269       OOTRACEERR1("Failed to create RAS socket\n");
270       pGkClient->state = GkClientFailed;
271       return OO_FAILED;
272    }
273    if(pGkClient->localRASPort)
274    {
275       inet_pton(AF_INET, pGkClient->localRASIP, &ipaddrs);
276       if( (ret=ooSocketBind( pGkClient->rasSocket, ipaddrs, 
277            pGkClient->localRASPort))!=ASN_OK ) 
278       {
279          OOTRACEERR1("ERROR:Failed to create RAS channel\n");
280          pGkClient->state = GkClientFailed;
281          return OO_FAILED;
282       }
283    }
284    else {
285       ret = ooBindPort (OOUDP, pGkClient->rasSocket, pGkClient->localRASIP);
286       if(ret == OO_FAILED)
287       {
288          OOTRACEERR1("ERROR: Failed to bind port to RAS socket\n");
289          pGkClient->state = GkClientFailed;
290          return OO_FAILED;
291       }
292       pGkClient->localRASPort = ret;
293    }
294    /* Test Code NOTE- This doesn't work..:(( Have to fix this */
295    /* If multihomed, get ip from socket */
296    if(!strcmp(pGkClient->localRASIP, "0.0.0.0"))
297    {
298       OOTRACEDBGA1("Determining ip address for RAS channel "
299                    "multihomed mode. \n");
300       ret = ooSocketGetIpAndPort(pGkClient->rasSocket, pGkClient->localRASIP, 
301                                  20, &pGkClient->localRASPort, NULL);
302       if(ret != ASN_OK)
303       {
304          OOTRACEERR1("Error:Failed to retrieve local ip and port from "
305                      "socket for RAS channel(multihomed).\n");
306          pGkClient->state = GkClientFailed;
307          return OO_FAILED;
308       }
309       OOTRACEDBGA3("Using local ip %s and port %d for RAS channel"
310                    "(multihomedMode).\n", pGkClient->localRASIP, 
311                    pGkClient->localRASPort);
312    }
313    /* End of Test code */
314    OOTRACEINFO1("H323 RAS channel creation - successful\n");
315    return OO_OK;
316 }
317
318
319 int ooGkClientCloseChannel(ooGkClient *pGkClient)
320 {
321    int ret;
322    if(pGkClient->rasSocket != 0)
323    {
324       ret = ooSocketClose(pGkClient->rasSocket);
325       if(ret != ASN_OK)
326       {
327          OOTRACEERR1("Error: failed to close RAS channel\n");
328          pGkClient->rasSocket = 0;
329          return OO_FAILED;
330       }
331       pGkClient->rasSocket = 0;
332    }
333    OOTRACEINFO1("Closed RAS channel\n");
334    return OO_OK;
335 }
336
337
338 /**
339  * Fill vendor data in RAS message structure.
340  */
341
342 void ooGkClientFillVendor
343    (ooGkClient *pGkClient, H225VendorIdentifier *pVendor )
344 {
345    pVendor->vendor.t35CountryCode = gH323ep.t35CountryCode;
346    pVendor->vendor.t35Extension = gH323ep.t35Extension;
347    pVendor->vendor.manufacturerCode = gH323ep.manufacturerCode;
348    pVendor->enterpriseNumber.numids=0;
349    if(gH323ep.productID)
350    {
351       pVendor->m.productIdPresent = TRUE;
352       pVendor->productId.numocts = ASN1MIN(strlen(gH323ep.productID), 
353                                              sizeof(pVendor->productId.data));
354       memcpy(pVendor->productId.data, gH323ep.productID, 
355                                                   pVendor->productId.numocts);
356    }
357    if(gH323ep.versionID)
358    {
359       pVendor->m.versionIdPresent = 1;
360       pVendor->versionId.numocts = ASN1MIN(strlen(gH323ep.versionID), 
361                                              sizeof(pVendor->versionId.data));
362       memcpy(pVendor->versionId.data, gH323ep.versionID, 
363                                                  pVendor->versionId.numocts); 
364    }
365 }   
366
367
368 int ooGkClientReceive(ooGkClient *pGkClient)
369 {
370    ASN1OCTET recvBuf[ASN_K_ENCBUFSIZ];
371    int recvLen;
372    char remoteHost[32];
373    int iFromPort=0;
374    OOCTXT *pctxt=NULL;
375    H225RasMessage *pRasMsg=NULL;
376    int iRet=OO_OK;
377    
378    ast_mutex_lock(&pGkClient->Lock);
379    pctxt = &pGkClient->msgCtxt;
380
381    recvLen = ooSocketRecvFrom(pGkClient->rasSocket, recvBuf, 2048, remoteHost,
382                               32, &iFromPort);
383    if(recvLen <0)
384    {
385       OOTRACEERR1("Error:Failed to receive RAS message\n");
386       ast_mutex_unlock(&pGkClient->Lock);
387       return OO_FAILED;
388    }
389    OOTRACEDBGA1("GkClient Received RAS Message\n");
390   
391    /* Verify the gk */
392    if(pGkClient->discoveryComplete)
393    {
394       if((strncmp(pGkClient->gkRasIP, remoteHost,strlen(pGkClient->gkRasIP)))||
395          (pGkClient->gkRasPort!= iFromPort) )
396       {
397          OOTRACEWARN3("WARN:Ignoring message received from unknown gatekeeper "
398                       "%s:%d\n", remoteHost, iFromPort);
399          ast_mutex_unlock(&pGkClient->Lock);
400          return OO_OK;
401       }
402    }
403
404    if(ASN_OK != setPERBuffer (pctxt, recvBuf, recvLen, TRUE ) )
405    {
406       OOTRACEERR1("Error:Failed to set PER buffer for RAS message decoding\n");
407       memReset(pctxt);
408       pGkClient->state = GkClientFailed;
409       ast_mutex_unlock(&pGkClient->Lock);
410       return OO_FAILED;
411    }      
412    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
413    if(!pRasMsg)
414    {
415       OOTRACEERR1("Error: Failed to allocate memory for RAS message\n");
416       memReset(pctxt);
417       pGkClient->state = GkClientFailed;
418       ast_mutex_unlock(&pGkClient->Lock);
419       return OO_FAILED;
420    }
421 #ifndef _COMPACT
422    initializePrintHandler(&printHandler, "Received RAS Message");
423    /* Add event handler to list */
424    setEventHandler (pctxt, &printHandler);
425 #endif
426    if(ASN_OK == asn1PD_H225RasMessage(pctxt, pRasMsg))
427    {
428 #ifndef _COMPACT
429       finishPrint();
430       removeEventHandler(pctxt);
431 #endif
432       iRet=ooGkClientHandleRASMessage( pGkClient, pRasMsg );
433       if(iRet != OO_OK)
434       {
435          OOTRACEERR1("Error: Failed to handle received RAS message\n");
436          pGkClient->state = GkClientFailed;
437       }
438       memReset(pctxt);
439    }
440    else{
441       OOTRACEERR1("ERROR:Failed to decode received RAS message- ignoring"
442                   "received message.\n");
443 #ifndef _COMPACT
444       removeEventHandler(pctxt);
445 #endif
446       memReset(pctxt);
447       ast_mutex_unlock(&pGkClient->Lock);
448       return OO_FAILED;
449    }
450    ast_mutex_unlock(&pGkClient->Lock);
451    return iRet;
452 }
453
454
455
456
457 /**
458  * Manage incoming RAS message.
459  */
460
461 int ooGkClientHandleRASMessage(ooGkClient *pGkClient, H225RasMessage *pRasMsg)
462 {
463    int iRet = OO_OK;   
464    switch( pRasMsg->t)
465    {
466    case T_H225RasMessage_gatekeeperConfirm:
467       OOTRACEINFO1("Gatekeeper Confirmed (GCF) message received.\n");
468       iRet = ooGkClientHandleGatekeeperConfirm(pGkClient, 
469                                           pRasMsg->u.gatekeeperConfirm);
470       break;
471    case T_H225RasMessage_gatekeeperReject: 
472       OOTRACEINFO1("Gatekeeper Reject (GRJ) message received\n");
473       iRet = ooGkClientHandleGatekeeperReject(pGkClient, 
474                                               pRasMsg->u.gatekeeperReject);
475       break;
476    case T_H225RasMessage_registrationConfirm:   
477       OOTRACEINFO1("Registration Confirm (RCF) message received\n");
478       iRet = ooGkClientHandleRegistrationConfirm(pGkClient,  
479                                               pRasMsg->u.registrationConfirm );
480       break;
481    case T_H225RasMessage_registrationReject:
482       OOTRACEINFO1("Registration Reject (RRJ) message received.\n");
483       iRet = ooGkClientHandleRegistrationReject(pGkClient, 
484                                                 pRasMsg->u.registrationReject);
485       break;
486    case T_H225RasMessage_infoRequest:  
487       //ooRasSendIRR( psRasMsg->sMessage.u.infoRequest->requestSeqNum );
488       break;
489    case T_H225RasMessage_admissionConfirm:
490       OOTRACEINFO1("Admission Confirm (ACF) message received\n");
491       iRet = ooGkClientHandleAdmissionConfirm(pGkClient, 
492                                               pRasMsg->u.admissionConfirm);
493       break;
494    case T_H225RasMessage_unregistrationRequest:
495       OOTRACEINFO1("UnRegistration Request (URQ) message received.\n");
496       iRet = ooGkClientHandleUnregistrationRequest(pGkClient, 
497                                             pRasMsg->u.unregistrationRequest);
498       break;
499    case T_H225RasMessage_unregistrationConfirm:
500       OOTRACEINFO1("UnRegistration Confirm (UCF) message received.\n");
501       break;
502    case T_H225RasMessage_unregistrationReject:
503       OOTRACEINFO1("UnRegistration Reject (URJ) message received.\n");
504       break;
505    case T_H225RasMessage_admissionReject:
506       OOTRACEINFO1("Admission Reject (ARJ) message received.\n");
507       iRet = ooGkClientHandleAdmissionReject(pGkClient, 
508                                                    pRasMsg->u.admissionReject);
509       break;
510    case T_H225RasMessage_disengageConfirm:
511       iRet = ooGkClientHandleDisengageConfirm(pGkClient, 
512                                               pRasMsg->u.disengageConfirm);
513       break;
514    case T_H225RasMessage_disengageReject:
515    case T_H225RasMessage_bandwidthConfirm:
516    case T_H225RasMessage_bandwidthReject:
517    case T_H225RasMessage_locationRequest:
518    case T_H225RasMessage_locationConfirm:
519    case T_H225RasMessage_locationReject:
520    case T_H225RasMessage_infoRequestResponse:
521    case T_H225RasMessage_nonStandardMessage:
522    case T_H225RasMessage_unknownMessageResponse:
523    case T_H225RasMessage_requestInProgress:
524    case T_H225RasMessage_resourcesAvailableIndicate:
525    case T_H225RasMessage_resourcesAvailableConfirm:
526    case T_H225RasMessage_infoRequestAck:
527    case T_H225RasMessage_infoRequestNak:
528    case T_H225RasMessage_serviceControlIndication:
529    case T_H225RasMessage_serviceControlResponse:
530    case T_H225RasMessage_admissionConfirmSequence:
531    default:
532       /* Unhandled RAS message */
533       iRet= OO_OK;
534    }
535
536    return iRet;
537 }
538
539 #ifndef _COMPACT
540 void ooGkClientPrintMessage
541    (ooGkClient *pGkClient, ASN1OCTET *msg, ASN1UINT len)
542 {
543    OOCTXT ctxt;
544    H225RasMessage rasMsg;
545    int ret; 
546
547    initContext(&ctxt);
548    setPERBuffer(&ctxt, msg, len, TRUE);
549    initializePrintHandler(&printHandler, "Sending RAS Message");
550    setEventHandler(&ctxt, &printHandler);
551
552    ret = asn1PD_H225RasMessage(&ctxt, &rasMsg);
553    if(ret != ASN_OK)
554    {
555       OOTRACEERR1("Error: Failed to decode RAS message\n");
556    }
557    finishPrint();
558    freeContext(&ctxt);
559 }
560 #endif
561 /**
562  * Encode and send RAS message.
563  */
564
565 int ooGkClientSendMsg(ooGkClient *pGkClient, H225RasMessage *pRasMsg)
566 {
567    ASN1OCTET msgBuf[MAXMSGLEN];
568    ASN1OCTET *msgPtr=NULL;
569    int  iLen;
570
571    OOCTXT *pctxt = &pGkClient->msgCtxt;
572
573    setPERBuffer( pctxt, msgBuf, MAXMSGLEN, TRUE );
574    if ( ASN_OK == asn1PE_H225RasMessage(pctxt, pRasMsg) )
575    {
576       OOTRACEDBGC1("Ras message encoding - successful\n");
577    }
578    else {
579       OOTRACEERR1("Error: RAS message encoding failed\n");
580       return OO_FAILED;
581    }
582
583    msgPtr = encodeGetMsgPtr( pctxt, &iLen );
584    /* If gatekeeper specified or have been discovered */
585    if(pGkClient->gkMode == RasUseSpecificGatekeeper || 
586       pGkClient->discoveryComplete)
587    {
588       if(ASN_OK != ooSocketSendTo( pGkClient->rasSocket, msgPtr, iLen, 
589                                    pGkClient->gkRasIP, pGkClient->gkRasPort))
590       {
591          OOTRACEERR1("Error sending RAS message\n");
592          return OO_FAILED;
593       }
594    }
595    else if(pGkClient->gkMode == RasDiscoverGatekeeper && 
596            !pGkClient->discoveryComplete) { 
597       if(ASN_OK != ooSocketSendTo(pGkClient->rasSocket, msgPtr, iLen, 
598                                        MULTICAST_GKADDRESS, MULTICAST_GKPORT))
599       {
600          OOTRACEERR1("Error sending multicast RAS message\n" );
601          return OO_FAILED;
602       }
603    }
604    else {/* should never go here */ 
605       OOTRACEERR1("Error: GkClient in invalid state.\n");
606       return OO_FAILED;
607    }
608 #ifndef _COMPACT
609    ooGkClientPrintMessage(pGkClient, msgPtr, iLen);
610 #endif
611    return OO_OK;
612 }
613
614
615
616 int ooGkClientSendGRQ(ooGkClient *pGkClient)
617 {
618    int iRet;
619    H225RasMessage *pRasMsg=NULL;
620    H225GatekeeperRequest *pGkReq=NULL;
621    H225TransportAddress_ipAddress *pRasAddress;
622    OOCTXT *pctxt = &pGkClient->msgCtxt;
623    ooGkClientTimerCb *cbData=NULL;
624
625    ast_mutex_lock(&pGkClient->Lock);
626
627    /* Allocate memory for RAS message */
628    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
629    if(!pRasMsg)
630    {
631       OOTRACEERR1("Error: Memory allocation for GRQ RAS message failed\n");
632       pGkClient->state = GkClientFailed;
633       ast_mutex_unlock(&pGkClient->Lock);
634       return OO_FAILED;
635    }
636
637    pGkReq = (H225GatekeeperRequest*)memAlloc(pctxt, 
638                                                 sizeof(H225GatekeeperRequest));
639    if(!pGkReq)
640    {
641       OOTRACEERR1("Error:Memory allocation for GRQ failed\n");
642       memReset(pctxt);
643       pGkClient->state = GkClientFailed;
644       ast_mutex_unlock(&pGkClient->Lock);
645       return OO_FAILED;
646    }
647    memset(pGkReq, 0, sizeof(H225GatekeeperRequest));
648    pRasMsg->t = T_H225RasMessage_gatekeeperRequest;
649    pRasMsg->u.gatekeeperRequest = pGkReq;
650
651    /* Populate message structure */
652    pGkReq->requestSeqNum = pGkClient->requestSeqNum++;
653    if ( !pGkReq->requestSeqNum )
654       pGkReq->requestSeqNum = pGkClient->requestSeqNum++;
655
656    pGkReq->protocolIdentifier = gProtocolID;
657    pGkReq->m.nonStandardDataPresent=0;
658    pGkReq->rasAddress.t=T_H225TransportAddress_ipAddress; /* IPv4 address */
659    pRasAddress = (H225TransportAddress_ipAddress*)memAlloc(pctxt, 
660                                       sizeof(H225TransportAddress_ipAddress));
661    if(!pRasAddress)
662    {
663       OOTRACEERR1("Error: Memory allocation for Ras Address of GRQ message "
664                   "failed\n");
665       memReset(&pGkClient->msgCtxt);
666       pGkClient->state = GkClientFailed;
667       ast_mutex_unlock(&pGkClient->Lock);
668       return OO_FAILED;
669    }
670
671  
672    inet_pton(AF_INET, pGkClient->localRASIP, pRasAddress->ip.data);
673
674    pRasAddress->ip.numocts = 4;
675    pRasAddress->port = pGkClient->localRASPort;
676    pGkReq->rasAddress.u.ipAddress = pRasAddress;
677
678    /* Pose as gateway or terminal as per config */
679    if(gH323ep.isGateway)
680       pGkReq->endpointType.m.gatewayPresent = TRUE;
681    else
682       pGkReq->endpointType.m.terminalPresent = TRUE;
683
684    pGkReq->endpointType.m.nonStandardDataPresent=0;
685    pGkReq->endpointType.m.vendorPresent=1;
686
687    ooGkClientFillVendor(pGkClient, &pGkReq->endpointType.vendor);
688
689
690    pGkReq->m.endpointAliasPresent=TRUE;
691    if(OO_OK != ooPopulateAliasList(&pGkClient->msgCtxt, gH323ep.aliases, 
692                                       &pGkReq->endpointAlias, 0))
693    {
694       OOTRACEERR1("Error Failed to fill alias information for GRQ message\n");
695       memReset(&pGkClient->msgCtxt);
696       pGkClient->state = GkClientFailed;
697       ast_mutex_unlock(&pGkClient->Lock);
698       return OO_FAILED;
699    }
700    iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
701    if(iRet != OO_OK)
702    {
703       OOTRACEERR1("Error: Failed to send GRQ message\n");
704       memReset(&pGkClient->msgCtxt);
705       pGkClient->state = GkClientFailed;
706       ast_mutex_unlock(&pGkClient->Lock);
707       return OO_FAILED;
708    }
709    OOTRACEINFO1("Sent GRQ message\n");
710    cbData = (ooGkClientTimerCb*) memAlloc
711                                (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
712    if(!cbData)
713    {
714       OOTRACEERR1("Error:Failed to allocate memory to GRQ timer callback\n");
715       pGkClient->state = GkClientFailed;
716       ast_mutex_unlock(&pGkClient->Lock);
717       return OO_FAILED;
718    }
719    cbData->timerType = OO_GRQ_TIMER;
720    cbData->pGkClient = pGkClient;
721    if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList, 
722                      &ooGkClientGRQTimerExpired, pGkClient->grqTimeout, 
723                      cbData, FALSE))      
724    {
725       OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
726       memFreePtr(&pGkClient->ctxt, cbData);
727       pGkClient->state = GkClientFailed;
728       ast_mutex_unlock(&pGkClient->Lock);
729       return OO_FAILED;
730    }
731    ast_mutex_unlock(&pGkClient->Lock);
732    return OO_OK;
733 }
734
735 int ooGkClientHandleGatekeeperReject
736    (ooGkClient *pGkClient, H225GatekeeperReject *pGatekeeperReject)
737 {
738    unsigned int x=0;
739    DListNode *pNode = NULL;
740    OOTimer *pTimer = NULL;
741
742    if(pGkClient->gkMode == RasUseSpecificGatekeeper)
743    {
744       /* delete the corresponding GRQ timer */
745       for(x=0; x<pGkClient->timerList.count; x++)
746       {
747          pNode =  dListFindByIndex(&pGkClient->timerList, x);
748          pTimer = (OOTimer*)pNode->data;
749          if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_GRQ_TIMER)
750          {
751             memFreePtr(&pGkClient->ctxt, pTimer->cbData);
752             ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
753             OOTRACEDBGA1("Deleted GRQ Timer.\n");
754             break;
755          }
756       }
757  
758       pGkClient->state = GkClientGkErr;
759       switch(pGatekeeperReject->rejectReason.t)
760       {
761       case T_H225GatekeeperRejectReason_resourceUnavailable:
762          OOTRACEERR1("Error: Gatekeeper Reject - Resource Unavailable\n");
763          break;
764       case T_H225GatekeeperRejectReason_terminalExcluded:
765          OOTRACEERR1("Error: Gatekeeper Reject - Terminal Excluded\n");
766          break;
767       case T_H225GatekeeperRejectReason_invalidRevision:
768          OOTRACEERR1("Error: Gatekeeper Reject - Invalid Revision\n");
769          break;
770       case T_H225GatekeeperRejectReason_undefinedReason:
771          OOTRACEERR1("Error: Gatekeeper Reject - Undefined Reason\n");
772          break;
773       case T_H225GatekeeperRejectReason_securityDenial:
774          OOTRACEERR1("Error: Gatekeeper Reject - Security Denial\n");
775          break;
776       case T_H225GatekeeperRejectReason_genericDataReason:
777          OOTRACEERR1("Error: Gatekeeper Reject - Generic Data Reason\n");
778          break;
779       case T_H225GatekeeperRejectReason_neededFeatureNotSupported:
780          OOTRACEERR1("Error: Gatekeeper Reject - Needed Feature Not "
781                      "Supported\n");
782          break;
783       case T_H225GatekeeperRejectReason_securityError:
784          OOTRACEERR1("Error:Gatekeeper Reject - Security Error\n");
785          break;
786       default:
787          OOTRACEERR1("Error: Gatekeeper Reject - Invalid reason\n");
788       }
789       return OO_OK;
790    }
791    OOTRACEDBGB1("Gatekeeper Reject response received for multicast GRQ "
792                 "request\n");
793    return OO_OK;
794
795 }
796
797 int ooGkClientHandleGatekeeperConfirm
798    (ooGkClient *pGkClient, H225GatekeeperConfirm *pGatekeeperConfirm)
799 {
800    int iRet=0;
801    unsigned int x=0;
802    DListNode *pNode = NULL;
803    OOTimer *pTimer = NULL;
804    H225TransportAddress_ipAddress *pRasAddress;
805
806    if(pGkClient->discoveryComplete)
807    {
808       OOTRACEDBGB1("Ignoring GKConfirm as Gatekeeper has been discovered\n");
809       return OO_OK;
810    }
811
812    if(pGatekeeperConfirm->m.gatekeeperIdentifierPresent) 
813    {
814       pGkClient->gkId.nchars = pGatekeeperConfirm->gatekeeperIdentifier.nchars;
815       if (pGkClient->gkId.data) {
816          memFreePtr(&pGkClient->ctxt, pGkClient->gkId.data);
817       }
818       pGkClient->gkId.data = (ASN116BITCHAR*)memAlloc(&pGkClient->ctxt,
819                               sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
820       if(!pGkClient->gkId.data)
821       {
822          OOTRACEERR1("Error:Failed to allocate memory for GK ID data\n");
823          pGkClient->state = GkClientFailed;
824          return OO_FAILED;
825       }
826
827       memcpy(pGkClient->gkId.data, 
828              pGatekeeperConfirm->gatekeeperIdentifier.data,
829              sizeof(ASN116BITCHAR)* pGkClient->gkId.nchars);
830    }
831    else{
832       OOTRACEINFO1("ERROR:No Gatekeeper ID present in received GKConfirmed "
833                   "message\n");
834       pGkClient->gkId.nchars = 0;
835    }
836    
837    /* Extract Gatekeeper's RAS address */
838    if(pGatekeeperConfirm->rasAddress.t != T_H225TransportAddress_ipAddress)
839    {
840       OOTRACEERR1("ERROR:Unsupported RAS address type in received Gk Confirm"
841                   " message.\n");
842       pGkClient->state = GkClientGkErr;
843       return OO_FAILED;
844    }
845    pRasAddress =   pGatekeeperConfirm->rasAddress.u.ipAddress;
846    sprintf(pGkClient->gkRasIP, "%d.%d.%d.%d", pRasAddress->ip.data[0],
847                                               pRasAddress->ip.data[1],
848                                               pRasAddress->ip.data[2], 
849                                               pRasAddress->ip.data[3]);
850    pGkClient->gkRasPort = pRasAddress->port;
851    
852    pGkClient->discoveryComplete = TRUE;
853    pGkClient->state = GkClientDiscovered;
854    OOTRACEINFO1("Gatekeeper Confirmed\n");
855
856
857    /* Delete the corresponding GRQ timer */
858    for(x=0; x<pGkClient->timerList.count; x++)
859    {
860       pNode =  dListFindByIndex(&pGkClient->timerList, x);
861       pTimer = (OOTimer*)pNode->data;
862       if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_GRQ_TIMER)
863       {
864          memFreePtr(&pGkClient->ctxt, pTimer->cbData);
865          ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
866          OOTRACEDBGA1("Deleted GRQ Timer.\n");
867       }
868    }
869
870    iRet = ooGkClientSendRRQ(pGkClient, FALSE);
871    if(iRet != OO_OK)
872    {
873       OOTRACEERR1("Error:Failed to send initial RRQ\n");
874       return OO_FAILED;
875    }
876    return OO_OK;
877 }
878
879 /**
880  * Send RRQ.
881  */
882
883 int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive)
884 {
885    int iRet;
886    H225RasMessage *pRasMsg=NULL;
887    H225RegistrationRequest *pRegReq=NULL;
888    OOCTXT *pctxt=NULL;
889    H225TransportAddress *pTransportAddress=NULL;
890    H225TransportAddress_ipAddress *pIpAddress=NULL;
891    ooGkClientTimerCb *cbData =NULL;
892    H225SupportedProtocols *pProtocol = NULL;
893    H225VoiceCaps *pVoiceCaps = NULL;
894
895    ast_mutex_lock(&pGkClient->Lock);
896
897    pctxt = &pGkClient->msgCtxt;
898
899    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
900    if(!pRasMsg)
901    {
902       OOTRACEERR1("Error: Memory allocation for RRQ RAS message failed\n");
903       pGkClient->state = GkClientFailed;
904       ast_mutex_unlock(&pGkClient->Lock);
905       return OO_FAILED;
906    }
907
908    pRegReq = (H225RegistrationRequest*)memAlloc(pctxt, 
909                                           sizeof(H225RegistrationRequest));
910    if(!pRegReq)
911    {
912       OOTRACEERR1("Error:Memory allocation for RRQ failed\n");
913       memReset(pctxt);
914       pGkClient->state = GkClientFailed;
915       ast_mutex_unlock(&pGkClient->Lock);
916       return OO_FAILED;
917    }
918    memset(pRegReq, 0, sizeof(H225RegistrationRequest));
919    pRasMsg->t = T_H225RasMessage_registrationRequest;
920    pRasMsg->u.registrationRequest = pRegReq;
921    
922    pRegReq->protocolIdentifier = gProtocolID;
923    pRegReq->m.nonStandardDataPresent=0;
924    /* Populate CallSignal Address List*/
925    pTransportAddress = (H225TransportAddress*) memAlloc(pctxt, 
926                                                  sizeof(H225TransportAddress));
927    pIpAddress = (H225TransportAddress_ipAddress*) memAlloc(pctxt,
928                                        sizeof(H225TransportAddress_ipAddress));
929    if(!pTransportAddress || !pIpAddress)
930    {
931       OOTRACEERR1("Error:Failed to allocate memory for signalling address of "
932                   "RRQ message\n");
933       memReset(pctxt);
934       pGkClient->state = GkClientFailed;
935       ast_mutex_unlock(&pGkClient->Lock);
936       return OO_FAILED;
937    }
938    pTransportAddress->t = T_H225TransportAddress_ipAddress;
939    pTransportAddress->u.ipAddress = pIpAddress;
940    inet_pton(AF_INET, pGkClient->localRASIP, pIpAddress->ip.data);
941    pIpAddress->ip.numocts = 4;
942    pIpAddress->port = gH323ep.listenPort;
943    
944    dListInit(&pRegReq->callSignalAddress);
945    dListAppend(pctxt, &pRegReq->callSignalAddress, 
946                                        (void*)pTransportAddress);
947
948    /* Populate RAS Address List*/
949    pTransportAddress = NULL;
950    pIpAddress = NULL;
951    pTransportAddress = (H225TransportAddress*) memAlloc(pctxt, 
952                                                  sizeof(H225TransportAddress));
953    pIpAddress = (H225TransportAddress_ipAddress*) memAlloc(pctxt,
954                                        sizeof(H225TransportAddress_ipAddress));
955    if(!pTransportAddress || !pIpAddress)
956    {
957       OOTRACEERR1("Error:Failed to allocate memory for RAS address of "
958                   "RRQ message\n");
959       memReset(pctxt);
960       pGkClient->state = GkClientFailed;
961       ast_mutex_unlock(&pGkClient->Lock);
962       return OO_FAILED;
963    }
964
965    pTransportAddress->t = T_H225TransportAddress_ipAddress;
966    pTransportAddress->u.ipAddress = pIpAddress;
967    
968    inet_pton(AF_INET, pGkClient->localRASIP, pIpAddress->ip.data);
969
970    pIpAddress->ip.numocts = 4;
971    pIpAddress->port = pGkClient->localRASPort;
972    
973    dListInit(&pRegReq->rasAddress);
974    dListAppend(pctxt, &pRegReq->rasAddress, 
975                                        (void*)pTransportAddress);
976    
977    /* Pose as gateway or terminal as per config */
978    if(gH323ep.isGateway)
979       pRegReq->terminalType.m.gatewayPresent = TRUE;
980    else
981       pRegReq->terminalType.m.terminalPresent = TRUE;
982
983    pRegReq->terminalType.m.vendorPresent=TRUE;
984    ooGkClientFillVendor(pGkClient, &pRegReq->terminalType.vendor );
985
986    if (gH323ep.isGateway) {
987       pRegReq->terminalType.gateway.m.protocolPresent = TRUE;
988       pProtocol = (H225SupportedProtocols*) memAlloc(pctxt,
989                                        sizeof(H225SupportedProtocols));
990       pVoiceCaps = (H225VoiceCaps*) memAlloc(pctxt, sizeof(H225VoiceCaps));
991       if(!pProtocol || !pVoiceCaps) {
992         OOTRACEERR1("Error:Failed to allocate memory for protocol info of "
993                   "RRQ message\n");
994         memReset(pctxt);
995         pGkClient->state = GkClientFailed;
996         ast_mutex_unlock(&pGkClient->Lock);
997         return OO_FAILED;
998       }
999
1000       memset(pVoiceCaps, 0, sizeof(H225VoiceCaps));
1001       memset(pProtocol, 0, sizeof(H225SupportedProtocols));
1002
1003       pVoiceCaps->m.supportedPrefixesPresent = TRUE;
1004       ooPopulatePrefixList(pctxt, gH323ep.aliases, &pVoiceCaps->supportedPrefixes);
1005
1006       pProtocol->t = T_H225SupportedProtocols_voice;
1007       pProtocol->u.voice = pVoiceCaps;
1008    
1009       dListInit(&pRegReq->terminalType.gateway.protocol);
1010       dListAppend(pctxt, &pRegReq->terminalType.gateway.protocol, 
1011                                        (void*)pProtocol);
1012
1013    }
1014
1015    pRegReq->m.terminalAliasPresent=TRUE;
1016    if(OO_OK != ooPopulateAliasList(pctxt, gH323ep.aliases, 
1017                                      &pRegReq->terminalAlias, 0)) {
1018      OOTRACEERR1("Error filling alias for RRQ\n");
1019      memReset(pctxt); 
1020      pGkClient->state = GkClientFailed;
1021      ast_mutex_unlock(&pGkClient->Lock);
1022      return OO_FAILED;
1023    }
1024    
1025    if (pGkClient->gkId.nchars) {
1026     pRegReq->m.gatekeeperIdentifierPresent=TRUE;
1027     pRegReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
1028     pRegReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc
1029                          (pctxt, pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
1030     if(!pRegReq->gatekeeperIdentifier.data)
1031     {
1032       OOTRACEERR1("Error: Failed to allocate memory for GKIdentifier in RRQ "
1033                    "message.\n");
1034       memReset(pctxt);
1035       pGkClient->state = GkClientFailed;
1036       ast_mutex_unlock(&pGkClient->Lock);
1037       return OO_FAILED;
1038     }
1039     memcpy(pRegReq->gatekeeperIdentifier.data, pGkClient->gkId.data, 
1040                                 pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
1041    }
1042    
1043    ooGkClientFillVendor(pGkClient, &pRegReq->endpointVendor);
1044    
1045    pRegReq->m.willSupplyUUIEsPresent=TRUE;
1046    pRegReq->willSupplyUUIEs=FALSE;
1047
1048    pRegReq->requestSeqNum = pGkClient->requestSeqNum++;
1049    if(!pRegReq->requestSeqNum)
1050       pRegReq->requestSeqNum = pGkClient->requestSeqNum++;
1051    
1052    pRegReq->discoveryComplete= pGkClient->discoveryComplete;
1053    pRegReq->m.keepAlivePresent=TRUE;
1054    pRegReq->keepAlive= keepAlive;
1055
1056    /*
1057     * Cisco Gatekeeper re-registration fix.  Thanks to Mike Tubby (mike@tubby.org) 28feb2007
1058     * Without this patch initial registration works, but re-registration fails!
1059     *
1060     * For light-weight re-registration, keepalive is set true
1061     * GK needs rasAddress, keepAlive, endpointIdentifier, gatekeeperIdentifier,
1062     * tokens, and timeToLive
1063     * GK will ignore all other params if KeepAlive is set.
1064     *
1065     */
1066    if(keepAlive) {
1067       /* KeepAlive, re-registration message...
1068          allocate storage for endpoint-identifier, and populate it from what the
1069          GK told us from the previous RCF. Only allocate on the first pass thru here */
1070       pRegReq->endpointIdentifier.data = 
1071            (ASN116BITCHAR*)memAlloc(pctxt, pGkClient->endpointId.nchars*sizeof(ASN116BITCHAR));
1072       if (pRegReq->endpointIdentifier.data) {
1073          pRegReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
1074          pRegReq->m.endpointIdentifierPresent = TRUE;
1075          memcpy(pRegReq->endpointIdentifier.data, pGkClient->endpointId.data, pGkClient->endpointId.nchars*sizeof(ASN116BITCHAR));
1076          OOTRACEINFO1("Sending RRQ for re-registration (with EndpointID)\n");
1077       }
1078       else {
1079          OOTRACEERR1("Error: Failed to allocate memory for EndpointIdentifier in RRQ \n");
1080          memReset(pctxt);
1081          pGkClient->state = GkClientFailed;
1082          ast_mutex_unlock(&pGkClient->Lock);
1083          return OO_FAILED;
1084       }
1085    }
1086
1087    pRegReq->m.timeToLivePresent = TRUE;
1088    pRegReq->timeToLive = pGkClient->regTimeout;
1089
1090    iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
1091    if(iRet != OO_OK)
1092    {
1093       OOTRACEERR1("Error: Failed to send RRQ message\n");
1094       memReset(pctxt);
1095       pGkClient->state = GkClientFailed;
1096       ast_mutex_unlock(&pGkClient->Lock);
1097       return OO_FAILED;
1098    }
1099    OOTRACEINFO1("Sent RRQ message \n");
1100    /* Start RRQ Timer */
1101    cbData = (ooGkClientTimerCb*) memAlloc
1102                             (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
1103    if(!cbData)
1104    {
1105       OOTRACEERR1("Error:Failed to allocate memory to RRQ timer callback\n");
1106       pGkClient->state = GkClientFailed;
1107       ast_mutex_unlock(&pGkClient->Lock);
1108       return OO_FAILED;
1109    }
1110    cbData->timerType = OO_RRQ_TIMER;
1111    cbData->pGkClient = pGkClient;
1112    if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList, 
1113                      &ooGkClientRRQTimerExpired, pGkClient->rrqTimeout, 
1114                      cbData, FALSE))      
1115    {
1116       OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
1117       memFreePtr(&pGkClient->ctxt, cbData);
1118       pGkClient->state = GkClientFailed;
1119       ast_mutex_unlock(&pGkClient->Lock);
1120       return OO_FAILED;
1121    }
1122    
1123    ast_mutex_unlock(&pGkClient->Lock);
1124    return OO_OK;
1125 }
1126
1127
1128
1129 /**
1130  * Manage incoming RCF message.
1131  */
1132
1133 int ooGkClientHandleRegistrationConfirm
1134    (ooGkClient *pGkClient, H225RegistrationConfirm *pRegistrationConfirm)
1135 {
1136    int i=0;
1137    unsigned int x=0;
1138    OOTimer *pTimer = NULL;
1139    DListNode *pNode = NULL;
1140    H225TransportAddress *pCallSigAddr=NULL;
1141    ooGkClientTimerCb *cbData;
1142    ASN1UINT regTTL=0;
1143    /* Extract Endpoint Id */
1144    if (pGkClient->endpointId.data)
1145         memFreePtr(&pGkClient->ctxt, pGkClient->endpointId.data);
1146    pGkClient->endpointId.nchars = 
1147                               pRegistrationConfirm->endpointIdentifier.nchars;
1148    pGkClient->endpointId.data = (ASN116BITCHAR*)memAlloc(&pGkClient->ctxt,
1149                           sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
1150    if(!pGkClient->endpointId.data)
1151    {
1152       OOTRACEERR1("Error:Failed to allocate memory for endpoint Id.\n");
1153       pGkClient->state = GkClientFailed;
1154       return OO_FAILED;
1155    }
1156    
1157    memcpy(pGkClient->endpointId.data, 
1158           pRegistrationConfirm->endpointIdentifier.data,
1159           sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
1160
1161    /* Extract GK Identifier */
1162    
1163    if(pRegistrationConfirm->m.gatekeeperIdentifierPresent && pGkClient->gkId.nchars == 0)
1164    {
1165       pGkClient->gkId.nchars = pRegistrationConfirm->gatekeeperIdentifier.nchars;
1166       pGkClient->gkId.data = (ASN116BITCHAR*)memAlloc(&pGkClient->ctxt,
1167                               sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
1168       if(!pGkClient->gkId.data)
1169       {
1170          OOTRACEERR1("Error:Failed to allocate memory for GK ID data\n");
1171          pGkClient->state = GkClientFailed;
1172          return OO_FAILED;
1173       }
1174
1175       memcpy(pGkClient->gkId.data, 
1176              pRegistrationConfirm->gatekeeperIdentifier.data,
1177              sizeof(ASN116BITCHAR)* pGkClient->gkId.nchars);
1178    }
1179
1180    /* Extract CallSignalling Address */
1181    for(i=0; i<(int)pRegistrationConfirm->callSignalAddress.count; i++)
1182    {
1183       pNode = dListFindByIndex(&pRegistrationConfirm->callSignalAddress, i);
1184       if(!pNode)
1185       {
1186          OOTRACEERR1("Error:Invalid Registration confirmed message\n");
1187          OOTRACEINFO1("Ignoring RCF, will retransmit RRQ after timeout\n");
1188          return OO_FAILED; 
1189       }
1190       pCallSigAddr = (H225TransportAddress*)pNode->data;
1191       if(pCallSigAddr->t != T_H225TransportAddress_ipAddress)
1192          continue;
1193       sprintf(pGkClient->gkCallSignallingIP, "%d.%d.%d.%d", 
1194                             pCallSigAddr->u.ipAddress->ip.data[0],
1195                             pCallSigAddr->u.ipAddress->ip.data[1],
1196                             pCallSigAddr->u.ipAddress->ip.data[2],
1197                             pCallSigAddr->u.ipAddress->ip.data[3]);
1198       pGkClient->gkCallSignallingPort = pCallSigAddr->u.ipAddress->port;
1199    }
1200    
1201    /* Update list of registered aliases*/
1202    if(pRegistrationConfirm->m.terminalAliasPresent)
1203    {
1204       ooGkClientUpdateRegisteredAliases(pGkClient, 
1205                                    &pRegistrationConfirm->terminalAlias, TRUE);
1206    }
1207    else{/* Everything registered*/
1208      ooGkClientUpdateRegisteredAliases(pGkClient, NULL, TRUE);
1209    }
1210
1211    /* Is keepAlive supported */
1212    if(pRegistrationConfirm->m.timeToLivePresent)
1213    {
1214       pGkClient->regTimeout = pRegistrationConfirm->timeToLive;
1215       OOTRACEINFO2("Gatekeeper supports KeepAlive, Registration TTL is %d\n",
1216                     pRegistrationConfirm->timeToLive);
1217
1218       if(pGkClient->regTimeout > DEFAULT_TTL_OFFSET)
1219          regTTL = pGkClient->regTimeout - DEFAULT_TTL_OFFSET;
1220       else {
1221          regTTL = pGkClient->regTimeout - 1; /* -1 due to some ops expire us few earlier */
1222          if (regTTL <= 0)
1223                 regTTL = 1;
1224       }
1225
1226       cbData = (ooGkClientTimerCb*) memAlloc
1227                                 (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
1228       if(!cbData)
1229       {
1230          OOTRACEERR1("Error:Failed to allocate memory for Regisration timer."
1231                      "\n");
1232          pGkClient->state = GkClientFailed;
1233          return OO_FAILED;
1234       }
1235       cbData->timerType = OO_REG_TIMER;
1236       cbData->pGkClient = pGkClient;
1237       if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList, 
1238                      &ooGkClientREGTimerExpired, regTTL, 
1239                      cbData, FALSE))
1240       {
1241          OOTRACEERR1("Error:Unable to create REG timer.\n ");
1242          memFreePtr(&pGkClient->ctxt, cbData);
1243          pGkClient->state = GkClientFailed;
1244          return OO_FAILED;
1245       }    
1246       
1247    }
1248    else{
1249       pGkClient->regTimeout = 0;
1250       OOTRACEINFO1("Gatekeeper does not support KeepAlive.\n");
1251    }
1252    /* Extract Pre-Granted ARQ */
1253    if(pRegistrationConfirm->m.preGrantedARQPresent)
1254    {
1255       memcpy(&pGkClient->gkInfo.preGrantedARQ, 
1256              &pRegistrationConfirm->preGrantedARQ,
1257              sizeof(H225RegistrationConfirm_preGrantedARQ));
1258    }
1259
1260
1261    /* First delete the corresponding RRQ timer */
1262    pNode = NULL;
1263    for(x=0; x<pGkClient->timerList.count; x++)
1264    {
1265       pNode =  dListFindByIndex(&pGkClient->timerList, x);
1266       pTimer = (OOTimer*)pNode->data;
1267       if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_RRQ_TIMER)
1268       {
1269          memFreePtr(&pGkClient->ctxt, pTimer->cbData);
1270          ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
1271          OOTRACEDBGA1("Deleted RRQ Timer.\n");
1272       }
1273    }
1274    pGkClient->state = GkClientRegistered;
1275    if(pGkClient->callbacks.onReceivedRegistrationConfirm)
1276       pGkClient->callbacks.onReceivedRegistrationConfirm(pRegistrationConfirm,
1277                                                               gH323ep.aliases);
1278    return OO_OK;
1279 }
1280
1281 int ooGkClientHandleRegistrationReject
1282    (ooGkClient *pGkClient, H225RegistrationReject *pRegistrationReject)
1283 {
1284    int iRet=0;
1285    unsigned int x=0;
1286    DListNode *pNode = NULL;
1287    OOTimer *pTimer = NULL;
1288    ooGkClientTimerCb *cbData=NULL;
1289
1290    /* First delete the corresponding RRQ timer */
1291    for(x=0; x<pGkClient->timerList.count; x++)
1292    {
1293       pNode =  dListFindByIndex(&pGkClient->timerList, x);
1294       pTimer = (OOTimer*)pNode->data;
1295       if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_RRQ_TIMER)
1296       {
1297          memFreePtr(&pGkClient->ctxt, pTimer->cbData);
1298          ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
1299          OOTRACEDBGA1("Deleted RRQ Timer.\n");
1300       }
1301    }
1302
1303    switch(pRegistrationReject->rejectReason.t)
1304    {
1305    case T_H225RegistrationRejectReason_discoveryRequired:
1306       OOTRACEINFO1("RRQ Rejected - Discovery Required\n");
1307
1308       pGkClient->discoveryComplete = FALSE;
1309       pGkClient->state = GkClientIdle;
1310       pGkClient->rrqRetries = 0;
1311       pGkClient->grqRetries = 0;
1312       if(OO_OK != ooGkClientSendGRQ(pGkClient))
1313       {
1314          OOTRACEERR1("Error:Failed to send GRQ message\n");
1315          return OO_FAILED;
1316       }
1317       return OO_OK;
1318    case T_H225RegistrationRejectReason_invalidRevision:
1319       OOTRACEERR1("RRQ Rejected - Invalid Revision\n");
1320       break;
1321    case T_H225RegistrationRejectReason_invalidCallSignalAddress:
1322       OOTRACEERR1("RRQ Rejected - Invalid CallSignalAddress\n");
1323       break;
1324    case T_H225RegistrationRejectReason_invalidRASAddress:
1325       OOTRACEERR1("RRQ Rejected - Invalid RAS Address\n");
1326       break;
1327    case T_H225RegistrationRejectReason_duplicateAlias:
1328       OOTRACEERR1("RRQ Rejected - Duplicate Alias\n");
1329       break;
1330    case T_H225RegistrationRejectReason_invalidTerminalType:
1331       OOTRACEERR1("RRQ Rejected - Invalid Terminal Type\n");
1332       break;
1333    case T_H225RegistrationRejectReason_undefinedReason:
1334       OOTRACEERR1("RRQ Rejected - Undefined Reason\n");
1335       break;
1336    case T_H225RegistrationRejectReason_transportNotSupported:
1337       OOTRACEERR1("RRQ Rejected - Transport Not supported\n");
1338       break;
1339    case T_H225RegistrationRejectReason_transportQOSNotSupported:
1340       OOTRACEERR1("RRQ Rejected - Transport QOS Not Supported\n");
1341       break;
1342    case T_H225RegistrationRejectReason_resourceUnavailable:
1343       OOTRACEERR1("RRQ Rejected - Resource Unavailable\n");
1344       break;
1345    case T_H225RegistrationRejectReason_invalidAlias:
1346       OOTRACEERR1("RRQ Rejected - Invalid Alias\n");
1347       break;
1348    case T_H225RegistrationRejectReason_securityDenial:
1349       OOTRACEERR1("RRQ Rejected - Security Denial\n");
1350       break;
1351    case T_H225RegistrationRejectReason_fullRegistrationRequired:
1352       OOTRACEINFO1("RRQ Rejected - Full Registration Required\n");
1353       pGkClient->state = GkClientDiscovered;
1354       pGkClient->rrqRetries = 0;
1355       iRet = ooGkClientSendRRQ(pGkClient, 0); /* No keepAlive */
1356       if(iRet != OO_OK){
1357          OOTRACEERR1("\nError: Full Registration transmission failed\n");
1358          return OO_FAILED;
1359       }
1360       return OO_OK;
1361    case T_H225RegistrationRejectReason_additiveRegistrationNotSupported:
1362       OOTRACEERR1("RRQ Rejected - Additive Registration Not Supported\n");
1363       break;
1364    case T_H225RegistrationRejectReason_invalidTerminalAliases:
1365       OOTRACEERR1("RRQ Rejected - Invalid Terminal Aliases\n");
1366       break;
1367    case T_H225RegistrationRejectReason_genericDataReason:
1368       OOTRACEERR1("RRQ Rejected - Generic Data Reason\n");
1369       break;
1370    case T_H225RegistrationRejectReason_neededFeatureNotSupported:
1371       OOTRACEERR1("RRQ Rejected - Needed Feature Not Supported\n");
1372       break;
1373    case T_H225RegistrationRejectReason_securityError:
1374       OOTRACEERR1("RRQ Rejected - Security Error\n");
1375       break;
1376    default:
1377       OOTRACEINFO1("RRQ Rejected - Invalid Reason\n");
1378    }
1379
1380    /* send again GRQ/RRQ's */
1381    ast_mutex_lock(&pGkClient->Lock);
1382    pGkClient->state = GkClientUnregistered;
1383    pGkClient->rrqRetries = 0;
1384    pGkClient->grqRetries = 0;
1385    pGkClient->discoveryComplete = FALSE;
1386
1387    cbData = (ooGkClientTimerCb*) memAlloc
1388                                (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
1389    if(!cbData)
1390    {
1391       OOTRACEERR1("Error:Failed to allocate memory to GRQ timer callback\n");
1392       pGkClient->state = GkClientFailed;
1393       ast_mutex_unlock(&pGkClient->Lock);
1394       return OO_FAILED;
1395    }
1396    cbData->timerType = OO_GRQ_TIMER;
1397    cbData->pGkClient = pGkClient;
1398    if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
1399                      &ooGkClientGRQTimerExpired, pGkClient->grqTimeout,
1400                      cbData, FALSE))
1401    {
1402       OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
1403       memFreePtr(&pGkClient->ctxt, cbData);
1404       pGkClient->state = GkClientFailed;
1405       ast_mutex_unlock(&pGkClient->Lock);
1406       return OO_FAILED;
1407    }
1408
1409    ast_mutex_unlock(&pGkClient->Lock);
1410
1411    return OO_OK;
1412
1413 }
1414
1415
1416 int ooGkClientSendURQ(ooGkClient *pGkClient, ooAliases *aliases)
1417 {
1418    int iRet;
1419    H225RasMessage *pRasMsg=NULL;
1420    H225UnregistrationRequest *pUnregReq=NULL;
1421    OOCTXT *pctxt=NULL;
1422    H225TransportAddress *pTransportAddress=NULL;
1423    H225TransportAddress_ipAddress *pIpAddress=NULL;
1424
1425    ast_mutex_lock(&pGkClient->Lock);
1426    pctxt = &pGkClient->msgCtxt;
1427
1428    OOTRACEDBGA1("Building Unregistration Request message\n");
1429
1430    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
1431    if(!pRasMsg)
1432    {
1433       OOTRACEERR1("Error: Memory allocation for URQ RAS message failed\n");
1434       pGkClient->state = GkClientFailed;
1435       ast_mutex_unlock(&pGkClient->Lock);
1436       return OO_FAILED;
1437    }
1438
1439    pUnregReq = (H225UnregistrationRequest*)memAlloc(pctxt, 
1440                                           sizeof(H225UnregistrationRequest));
1441    if(!pUnregReq)
1442    {
1443       OOTRACEERR1("Error:Memory allocation for URQ failed\n");
1444       memReset(pctxt);
1445       pGkClient->state = GkClientFailed;
1446       ast_mutex_unlock(&pGkClient->Lock);
1447       return OO_FAILED;
1448    }
1449    memset(pUnregReq, 0, sizeof(H225UnregistrationRequest));
1450    pRasMsg->t = T_H225RasMessage_unregistrationRequest;
1451    pRasMsg->u.unregistrationRequest = pUnregReq;
1452
1453    pUnregReq->requestSeqNum = pGkClient->requestSeqNum++;
1454    if(!pUnregReq->requestSeqNum)
1455       pUnregReq->requestSeqNum = pGkClient->requestSeqNum++;
1456
1457    
1458
1459  /* Populate CallSignal Address List*/
1460    pTransportAddress = (H225TransportAddress*) memAlloc(pctxt, 
1461                                                  sizeof(H225TransportAddress));
1462    pIpAddress = (H225TransportAddress_ipAddress*) memAlloc(pctxt,
1463                                        sizeof(H225TransportAddress_ipAddress));
1464    if(!pTransportAddress || !pIpAddress)
1465    {
1466       OOTRACEERR1("Error:Failed to allocate memory for signalling address of "
1467                   "RRQ message\n");
1468       memReset(pctxt);
1469       pGkClient->state = GkClientFailed;
1470       ast_mutex_unlock(&pGkClient->Lock);
1471       return OO_FAILED;
1472    }
1473    pTransportAddress->t = T_H225TransportAddress_ipAddress;
1474    pTransportAddress->u.ipAddress = pIpAddress;
1475    inet_pton(AF_INET, pGkClient->localRASIP, pIpAddress->ip.data);
1476    pIpAddress->ip.numocts = 4;
1477    pIpAddress->port = gH323ep.listenPort;
1478    
1479    dListInit(&pUnregReq->callSignalAddress);
1480    dListAppend(pctxt, &pUnregReq->callSignalAddress, 
1481                                        (void*)pTransportAddress);
1482
1483    /* Populate Endpoint Identifier */
1484    pUnregReq->m.endpointIdentifierPresent = TRUE;
1485    pUnregReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
1486    pUnregReq->endpointIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
1487                            sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
1488    if(!pUnregReq->endpointIdentifier.data)
1489    {
1490       OOTRACEERR1("Error: Failed to allocate memory for EndPoint Id in URQ "
1491                   "message.\n");
1492       memReset(pctxt);
1493       pGkClient->state = GkClientFailed;
1494       ast_mutex_unlock(&pGkClient->Lock);
1495       return OO_FAILED;
1496    }
1497    memcpy((void*)pUnregReq->endpointIdentifier.data, 
1498           (void*)pGkClient->endpointId.data,
1499           sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
1500
1501    /* Populate gatekeeper identifier */
1502    if (pGkClient->gkId.nchars) {
1503     pUnregReq->m.gatekeeperIdentifierPresent = TRUE;
1504     pUnregReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
1505     pUnregReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
1506                                  sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
1507     if(!pUnregReq->gatekeeperIdentifier.data)
1508     {
1509       OOTRACEERR1("Error:Failed to allocate memory for GKID of URQ message\n");
1510       memReset(pctxt);
1511       pGkClient->state = GkClientFailed;
1512       ast_mutex_unlock(&pGkClient->Lock);
1513       return OO_FAILED;
1514     }
1515     memcpy((void*)pUnregReq->gatekeeperIdentifier.data, 
1516           (void*)pGkClient->gkId.data, 
1517           sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);   
1518    }
1519
1520    /* Check whether specific aliases are to be unregistered*/
1521    if(aliases)
1522    {
1523       pUnregReq->m.endpointAliasPresent = TRUE;
1524       ooPopulateAliasList(pctxt, aliases, &pUnregReq->endpointAlias, 0);
1525    }
1526
1527   
1528    iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
1529    if(iRet != OO_OK)
1530    {
1531       OOTRACEERR1("Error:Failed to send UnregistrationRequest message\n");
1532       memReset(pctxt);
1533       pGkClient->state = GkClientFailed;
1534       ast_mutex_unlock(&pGkClient->Lock);
1535       return OO_FAILED;
1536    }
1537    pGkClient->state = GkClientUnregistered;
1538    OOTRACEINFO1("Unregistration Request message sent.\n");
1539
1540    ast_mutex_unlock(&pGkClient->Lock);
1541    return OO_OK;
1542 }               
1543
1544
1545
1546 int ooGkClientHandleUnregistrationRequest
1547    (ooGkClient *pGkClient, H225UnregistrationRequest * punregistrationRequest)
1548 {
1549    int iRet=0, x;
1550    OOTimer *pTimer = NULL;
1551    DListNode *pNode = NULL;
1552  
1553    /* Lets first send unregistration confirm message back to gatekeeper*/
1554    ooGkClientSendUnregistrationConfirm(pGkClient, 
1555                                       punregistrationRequest->requestSeqNum);
1556
1557    if(punregistrationRequest->m.endpointAliasPresent)
1558    {
1559       OOTRACEINFO1("Gatekeeper requested a list of aliases be unregistered\n");
1560       ooGkClientUpdateRegisteredAliases(pGkClient, 
1561                                 &punregistrationRequest->endpointAlias, FALSE);
1562    }
1563    else{
1564
1565       OOTRACEINFO1("Gatekeeper requested a all aliases to be unregistered\n");
1566       ooGkClientUpdateRegisteredAliases(pGkClient, NULL, FALSE);
1567       /* Send a fresh Registration request and if that fails, go back to
1568          Gatekeeper discovery.
1569       */
1570       OOTRACEINFO1("Sending fresh RRQ - as unregistration request received\n");
1571       pGkClient->rrqRetries = 0;
1572       pGkClient->state = GkClientDiscovered;
1573
1574
1575       /* delete the corresponding RRQ & REG timers */
1576         pNode = NULL;
1577         for(x=0; x<pGkClient->timerList.count; x++) {
1578                 pNode =  dListFindByIndex(&pGkClient->timerList, x);
1579                 pTimer = (OOTimer*)pNode->data;
1580                 if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_RRQ_TIMER) {
1581                         memFreePtr(&pGkClient->ctxt, pTimer->cbData);
1582                         ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
1583                         OOTRACEDBGA1("Deleted RRQ Timer.\n");
1584                 }
1585                 if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_REG_TIMER) {
1586                         memFreePtr(&pGkClient->ctxt, pTimer->cbData);
1587                         ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
1588                         OOTRACEDBGA1("Deleted REG Timer.\n");
1589                 }
1590         }
1591
1592       iRet = ooGkClientSendRRQ(pGkClient, 0); 
1593       if(iRet != OO_OK)
1594       {
1595          OOTRACEERR1("Error: Failed to send RRQ message\n");
1596          return OO_FAILED;
1597       }
1598    }
1599
1600
1601    if(pGkClient->callbacks.onReceivedUnregistrationRequest)
1602       pGkClient->callbacks.onReceivedUnregistrationRequest(
1603                                       punregistrationRequest, gH323ep.aliases);
1604    return OO_OK;
1605 }
1606
1607 int ooGkClientSendUnregistrationConfirm(ooGkClient *pGkClient, unsigned reqNo)
1608 {
1609    int iRet = OO_OK;
1610    OOCTXT *pctxt = &pGkClient->msgCtxt;   
1611    H225RasMessage *pRasMsg=NULL;
1612    H225UnregistrationConfirm *pUCF=NULL;
1613
1614    ast_mutex_lock(&pGkClient->Lock);
1615
1616    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
1617    pUCF = (H225UnregistrationConfirm*)memAlloc(pctxt, 
1618                                            sizeof(H225UnregistrationConfirm));
1619    if(!pRasMsg || !pUCF)
1620    {
1621       OOTRACEERR1("Error: Memory allocation for UCF RAS message failed\n");
1622       pGkClient->state = GkClientFailed;
1623       ast_mutex_unlock(&pGkClient->Lock);
1624       return OO_FAILED;
1625    }
1626    pRasMsg->t = T_H225RasMessage_unregistrationConfirm;
1627    pRasMsg->u.unregistrationConfirm = pUCF;
1628    memset(pUCF, 0, sizeof(H225UnregistrationConfirm));
1629    
1630    pUCF->requestSeqNum = reqNo;
1631    
1632    iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
1633    if(iRet != OO_OK)
1634    {
1635       OOTRACEERR1("Error:Failed to send UnregistrationConfirm message\n");
1636       memReset(pctxt);
1637       pGkClient->state = GkClientFailed;
1638       ast_mutex_unlock(&pGkClient->Lock);
1639       return OO_FAILED;
1640    }
1641    OOTRACEINFO1("Unregistration Confirm message sent for \n");
1642    memReset(pctxt);
1643
1644    ast_mutex_unlock(&pGkClient->Lock);
1645    return OO_OK;
1646 }
1647
1648
1649
1650
1651 int ooGkClientSendAdmissionRequest
1652    (ooGkClient *pGkClient, OOH323CallData *call, ASN1BOOL retransmit)
1653 {
1654    int iRet = 0;
1655    unsigned int x;
1656    DListNode *pNode;
1657    ooGkClientTimerCb *cbData=NULL;
1658    H225RasMessage *pRasMsg=NULL;
1659    OOCTXT* pctxt;
1660    H225AdmissionRequest *pAdmReq=NULL;
1661    H225TransportAddress_ipAddress *pIpAddressLocal =NULL, *pIpAddressRemote=NULL;
1662    ooAliases *destAliases = NULL, *srcAliases=NULL;
1663    RasCallAdmissionInfo *pCallAdmInfo=NULL;
1664    pctxt = &pGkClient->msgCtxt;
1665
1666    ast_mutex_lock(&pGkClient->Lock);
1667
1668    OOTRACEDBGA3("Building Admission Request for call (%s, %s)\n", 
1669                  call->callType, call->callToken);   
1670    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
1671    if(!pRasMsg)
1672    {
1673       OOTRACEERR3("Error:Memory - ooGkClientSendAdmissionRequest - "
1674                   "pRasMsg(%s, %s)\n", call->callType, call->callToken);
1675       pGkClient->state = GkClientFailed;
1676       ast_mutex_unlock(&pGkClient->Lock);
1677       return OO_FAILED;
1678    }
1679    pRasMsg->t = T_H225RasMessage_admissionRequest;
1680    pAdmReq = (H225AdmissionRequest*) memAlloc(pctxt, 
1681                                                  sizeof(H225AdmissionRequest));
1682    if(!pAdmReq)
1683    {
1684       OOTRACEERR3("Error:Memory - ooGkClientSendAdmissionRequest - "
1685                   "pAdmReq(%s, %s)\n", call->callType, call->callToken);
1686       memReset(pctxt);
1687       pGkClient->state = GkClientFailed;
1688       ast_mutex_unlock(&pGkClient->Lock);
1689       return OO_FAILED;
1690    }
1691    memset(pAdmReq, 0, sizeof(H225AdmissionRequest));
1692    pRasMsg->u.admissionRequest = pAdmReq;
1693    
1694    /* Populate call signalling addresses */
1695    pIpAddressLocal = (H225TransportAddress_ipAddress*)memAlloc(pctxt, 
1696                                      sizeof(H225TransportAddress_ipAddress));
1697    if(!ooUtilsIsStrEmpty(call->remoteIP))
1698       pIpAddressRemote = (H225TransportAddress_ipAddress*)memAlloc(pctxt, 
1699                                       sizeof(H225TransportAddress_ipAddress));
1700
1701    if(!pIpAddressLocal || (!ooUtilsIsStrEmpty(call->remoteIP) && (!pIpAddressRemote)))
1702    {
1703       OOTRACEERR1("Error:Failed to allocate memory for Call Signalling "
1704                   "Addresses of ARQ message\n");
1705       memReset(pctxt);
1706       pGkClient->state = GkClientFailed;
1707       ast_mutex_unlock(&pGkClient->Lock);
1708       return OO_FAILED;
1709    }
1710    inet_pton(AF_INET, pGkClient->localRASIP, pIpAddressLocal->ip.data);
1711
1712    pIpAddressLocal->ip.numocts = 4;
1713    pIpAddressLocal->port = gH323ep.listenPort;
1714
1715    if(!ooUtilsIsStrEmpty(call->remoteIP))
1716    {
1717       inet_pton(AF_INET, call->remoteIP, pIpAddressRemote->ip.data);
1718       pIpAddressRemote->ip.numocts = 4;
1719       pIpAddressRemote->port = call->remotePort;
1720    }
1721
1722    if(!strcmp(call->callType, "incoming"))
1723    {
1724       pAdmReq->m.destCallSignalAddressPresent = TRUE;
1725       pAdmReq->destCallSignalAddress.t = T_H225TransportAddress_ipAddress;
1726       pAdmReq->destCallSignalAddress.u.ipAddress = pIpAddressLocal;
1727       if(!ooUtilsIsStrEmpty(call->remoteIP))
1728       {
1729          pAdmReq->m.srcCallSignalAddressPresent = TRUE;
1730          pAdmReq->srcCallSignalAddress.t = T_H225TransportAddress_ipAddress;
1731          pAdmReq->srcCallSignalAddress.u.ipAddress = pIpAddressRemote;
1732       }
1733    }
1734    else {
1735       pAdmReq->m.srcCallSignalAddressPresent = TRUE;
1736       pAdmReq->srcCallSignalAddress.t = T_H225TransportAddress_ipAddress;
1737       pAdmReq->srcCallSignalAddress.u.ipAddress = pIpAddressLocal;
1738       if(!ooUtilsIsStrEmpty(call->remoteIP))
1739       {
1740          pAdmReq->m.destCallSignalAddressPresent = TRUE;
1741          pAdmReq->destCallSignalAddress.t = T_H225TransportAddress_ipAddress;
1742          pAdmReq->destCallSignalAddress.u.ipAddress = pIpAddressRemote;
1743       }
1744    }
1745
1746    /* Populate seq number */
1747    pAdmReq->requestSeqNum = pGkClient->requestSeqNum++;
1748    if(!pAdmReq->requestSeqNum)
1749       pAdmReq->requestSeqNum = pGkClient->requestSeqNum++;
1750
1751    /* Populate call type - For now only PointToPoint supported*/
1752    pAdmReq->callType.t = T_H225CallType_pointToPoint;
1753    
1754    /* Add call model to message*/
1755    pAdmReq->m.callModelPresent = 1;
1756    if(OO_TESTFLAG(call->flags, OO_M_GKROUTED))
1757       pAdmReq->callModel.t = T_H225CallModel_gatekeeperRouted;
1758    else
1759       pAdmReq->callModel.t = T_H225CallModel_direct;
1760
1761    /* Populate Endpoint Identifier */
1762    pAdmReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
1763    pAdmReq->endpointIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
1764                            sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
1765    if(!pAdmReq->endpointIdentifier.data)
1766    {
1767       OOTRACEERR3("Error:Memory -  ooGkClientSendAdmissionRequest - "
1768                   "endpointIdentifier.data(%s, %s)\n", call->callType, 
1769                   call->callToken);
1770       memReset(pctxt);
1771       pGkClient->state = GkClientFailed;
1772       ast_mutex_unlock(&pGkClient->Lock);
1773       return OO_FAILED;
1774    }
1775    memcpy((void*)pAdmReq->endpointIdentifier.data, 
1776           (void*)pGkClient->endpointId.data,
1777           sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
1778
1779    /* Get Destination And source aliases for call -  */
1780    if(!strcmp(call->callType, "incoming"))
1781    {
1782       if(call->ourAliases) 
1783          destAliases = call->ourAliases;
1784       else
1785          destAliases = gH323ep.aliases; 
1786
1787       srcAliases = call->remoteAliases;
1788    }
1789    else {
1790       if(call->ourAliases) 
1791          srcAliases = call->ourAliases;
1792       else
1793          srcAliases = gH323ep.aliases; 
1794
1795       destAliases = call->remoteAliases;
1796    }
1797
1798    /* Populate destination info */
1799    if(destAliases)
1800    {
1801       pAdmReq->m.destinationInfoPresent = 1;
1802       if(OO_OK != ooPopulateAliasList(&pGkClient->msgCtxt, destAliases,
1803                       &pAdmReq->destinationInfo, T_H225AliasAddress_dialedDigits))
1804       {
1805          OOTRACEERR1("Error:Failed to populate destination aliases - "
1806                     "ARQ message\n");
1807          pGkClient->state = GkClientFailed;
1808          memReset(pctxt);
1809          ast_mutex_unlock(&pGkClient->Lock);
1810          return OO_FAILED;
1811       }
1812    }
1813
1814    /* Populate Source Info */
1815    if(srcAliases)
1816    {
1817       iRet = ooPopulateAliasList(&pGkClient->msgCtxt, srcAliases,
1818                               &pAdmReq->srcInfo, 0);
1819       if(OO_OK != iRet)
1820       {
1821          OOTRACEERR1("Error:Failed to populate source aliases -ARQ message\n");
1822          memReset(pctxt);
1823          pGkClient->state = GkClientFailed;
1824          ast_mutex_unlock(&pGkClient->Lock);
1825          return OO_FAILED;
1826       }
1827    }
1828    
1829    /* Populate bandwidth*/
1830    pAdmReq->bandWidth = DEFAULT_BW_REQUEST;
1831    /* Populate call Reference */
1832    pAdmReq->callReferenceValue = call->callReference;
1833    
1834    /* populate conferenceID */
1835    memcpy((void*)&pAdmReq->conferenceID, (void*)&call->confIdentifier,
1836                                          sizeof(H225ConferenceIdentifier));
1837    /*populate answerCall */
1838    if(!strcmp(call->callType, "incoming"))
1839       pAdmReq->answerCall = TRUE;
1840    else
1841       pAdmReq->answerCall = FALSE;
1842
1843    /* Populate CanMapAlias */
1844    pAdmReq->m.canMapAliasPresent = TRUE;
1845    pAdmReq->canMapAlias = FALSE;
1846
1847    /* Populate call identifier */
1848    pAdmReq->m.callIdentifierPresent = TRUE;
1849    memcpy((void*)&pAdmReq->callIdentifier, (void*)&call->callIdentifier,
1850                                              sizeof(H225CallIdentifier));
1851
1852    /* Populate Gatekeeper Id */
1853    if (pGkClient->gkId.nchars) {
1854     pAdmReq->m.gatekeeperIdentifierPresent = TRUE;
1855     pAdmReq->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
1856     pAdmReq->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
1857                                  sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
1858     if(!pAdmReq->gatekeeperIdentifier.data)
1859     {
1860       OOTRACEERR1("Error:Failed to allocate memory for GKID of ARQ message\n");
1861       memReset(pctxt);
1862       pGkClient->state = GkClientFailed;
1863       ast_mutex_unlock(&pGkClient->Lock);
1864       return OO_FAILED;
1865     }
1866     memcpy((void*)pAdmReq->gatekeeperIdentifier.data, 
1867           (void*)pGkClient->gkId.data, 
1868           sizeof(ASN116BITCHAR)*pGkClient->gkId.nchars);
1869    }
1870
1871    pAdmReq->m.willSupplyUUIEsPresent = 1;
1872    pAdmReq->willSupplyUUIEs = FALSE;
1873
1874    /* Create RasCallAdmissionInfo */
1875    if(!retransmit)
1876    {
1877       pCallAdmInfo = (RasCallAdmissionInfo*)memAlloc(&pGkClient->ctxt, 
1878                                                 sizeof(RasCallAdmissionInfo));
1879       if(!pCallAdmInfo)
1880       {
1881          OOTRACEERR1("Error: Failed to allocate memory for new CallAdmission"
1882                   " Info entry\n");
1883          memReset(pctxt);
1884          pGkClient->state = GkClientFailed;
1885          ast_mutex_unlock(&pGkClient->Lock);
1886          return OO_FAILED;
1887       } 
1888
1889       pCallAdmInfo->call = call;
1890       pCallAdmInfo->retries = 0;
1891       pCallAdmInfo->requestSeqNum = pAdmReq->requestSeqNum;
1892       dListAppend(&pGkClient->ctxt, &pGkClient->callsPendingList,pCallAdmInfo);
1893    }
1894    else{
1895       for(x=0; x<pGkClient->callsPendingList.count; x++)
1896       {
1897          pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
1898          pCallAdmInfo = (RasCallAdmissionInfo*)pNode->data;
1899          if(pCallAdmInfo->call->callReference == call->callReference)
1900          {
1901             pCallAdmInfo->requestSeqNum = pAdmReq->requestSeqNum;
1902             break;
1903          }
1904       }
1905    }
1906    
1907    iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
1908    if(iRet != OO_OK)
1909    {
1910       OOTRACEERR1("Error:Failed to send AdmissionRequest message\n");
1911       memReset(pctxt);
1912       pGkClient->state = GkClientFailed;
1913       ast_mutex_unlock(&pGkClient->Lock);
1914       return OO_FAILED;
1915    }
1916    OOTRACEINFO3("Admission Request message sent for (%s, %s)\n", 
1917                  call->callType, call->callToken);
1918    memReset(pctxt);
1919     
1920    /* Add ARQ timer */
1921    cbData = (ooGkClientTimerCb*) memAlloc
1922                                (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
1923    if(!cbData)
1924    {
1925       OOTRACEERR1("Error:Failed to allocate memory for Regisration timer."
1926                   "\n");
1927       pGkClient->state = GkClientFailed;
1928       ast_mutex_unlock(&pGkClient->Lock);
1929       return OO_FAILED;
1930    }
1931    cbData->timerType = OO_ARQ_TIMER;
1932    cbData->pGkClient = pGkClient;
1933    cbData->pAdmInfo =  pCallAdmInfo;
1934    if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList, 
1935                   &ooGkClientARQTimerExpired, pGkClient->arqTimeout, 
1936                   cbData, FALSE))
1937    {
1938       OOTRACEERR1("Error:Unable to create ARQ timer.\n ");
1939       memFreePtr(&pGkClient->ctxt, cbData);
1940       pGkClient->state = GkClientFailed;
1941       ast_mutex_unlock(&pGkClient->Lock);
1942       return OO_FAILED;
1943    }    
1944    
1945    ast_mutex_unlock(&pGkClient->Lock);
1946    return OO_OK;
1947 }
1948
1949 /**
1950  * Manage incoming ACF message.
1951  */
1952
1953 int ooGkClientHandleAdmissionConfirm
1954    (ooGkClient *pGkClient, H225AdmissionConfirm *pAdmissionConfirm)
1955 {
1956    RasCallAdmissionInfo* pCallAdmInfo=NULL;
1957    unsigned int x, y;
1958    DListNode *pNode, *pNode1=NULL;
1959    H225TransportAddress_ipAddress * ipAddress=NULL;
1960    OOTimer *pTimer = NULL;
1961    char ip[20];
1962
1963    ast_mutex_lock(&pGkClient->Lock);
1964
1965    /* Search call in pending calls list */
1966    for(x=0 ; x<pGkClient->callsPendingList.count; x++)
1967    {
1968       pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
1969       pCallAdmInfo = (RasCallAdmissionInfo*) pNode->data;
1970       if(pCallAdmInfo->requestSeqNum == pAdmissionConfirm->requestSeqNum)
1971       {
1972          OOTRACEDBGC3("Found Pending call(%s, %s)\n", 
1973                       pCallAdmInfo->call->callType, 
1974                       pCallAdmInfo->call->callToken);
1975
1976          ast_mutex_lock(&pCallAdmInfo->call->GkLock);
1977
1978          /* Populate Remote IP */
1979          if(pAdmissionConfirm->destCallSignalAddress.t != 
1980                                       T_H225TransportAddress_ipAddress)
1981          {
1982             OOTRACEERR1("Error:Destination Call Signal Address provided by"
1983                         "Gatekeeper is not an IPv4 address\n");
1984             OOTRACEINFO1("Ignoring ACF, will wait for timeout and retransmit "
1985                          "ARQ\n");
1986             ast_mutex_unlock(&pCallAdmInfo->call->GkLock);
1987             ast_mutex_unlock(&pGkClient->Lock);
1988             ast_cond_signal(&pCallAdmInfo->call->gkWait);
1989             return OO_FAILED;
1990          }
1991          ipAddress = pAdmissionConfirm->destCallSignalAddress.u.ipAddress;
1992          
1993          sprintf(ip, "%d.%d.%d.%d", ipAddress->ip.data[0],
1994                                     ipAddress->ip.data[1],
1995                                     ipAddress->ip.data[2],
1996                                     ipAddress->ip.data[3]);
1997          if(strcmp(ip, "0.0.0.0")) {
1998 /* fix this when gk client will adopt to work with IPv6 */
1999             pCallAdmInfo->call->versionIP = 4;
2000             strcpy(pCallAdmInfo->call->remoteIP, ip);
2001          }
2002          pCallAdmInfo->call->remotePort = ipAddress->port;
2003          /* Update call model */
2004          if(pAdmissionConfirm->callModel.t == T_H225CallModel_direct)
2005          {
2006             if(OO_TESTFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED))
2007             {
2008                OOTRACEINFO3("Gatekeeper changed call model from GkRouted to "
2009                             "direct. (%s, %s)\n", pCallAdmInfo->call->callType,
2010                             pCallAdmInfo->call->callToken);
2011                OO_CLRFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED);
2012             }
2013          }
2014          
2015          if(pAdmissionConfirm->callModel.t == T_H225CallModel_gatekeeperRouted)
2016          {
2017             if(!OO_TESTFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED))
2018             {
2019                OOTRACEINFO3("Gatekeeper changed call model from direct to "
2020                             "GkRouted. (%s, %s)\n", 
2021                             pCallAdmInfo->call->callType,
2022                             pCallAdmInfo->call->callToken);
2023                OO_SETFLAG(pCallAdmInfo->call->flags, OO_M_GKROUTED);
2024             }
2025          }
2026
2027          /* Delete ARQ timer */
2028          for(y=0; y<pGkClient->timerList.count; y++)
2029          {
2030             pNode1 =  dListFindByIndex(&pGkClient->timerList, y);
2031             pTimer = (OOTimer*)pNode1->data;
2032             if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_ARQ_TIMER)
2033             {
2034                if(((ooGkClientTimerCb*)pTimer->cbData)->pAdmInfo == 
2035                                                                  pCallAdmInfo)
2036                {
2037                   memFreePtr(&pGkClient->ctxt, pTimer->cbData);
2038                   ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, 
2039                                                                        pTimer);
2040                   OOTRACEDBGA1("Deleted ARQ Timer.\n");
2041                   break;
2042                }
2043             }
2044          }       
2045          OOTRACEINFO3("Admission Confirm message received for (%s, %s)\n", 
2046                        pCallAdmInfo->call->callType, 
2047                        pCallAdmInfo->call->callToken);
2048
2049          pCallAdmInfo->call->callState = OO_CALL_CONNECTING;
2050
2051          dListRemove(&pGkClient->callsPendingList, pNode);
2052          dListAppend(&pGkClient->ctxt, &pGkClient->callsAdmittedList, 
2053                                                         pNode->data);
2054          memFreePtr(&pGkClient->ctxt, pNode);
2055          ast_mutex_unlock(&pCallAdmInfo->call->GkLock);
2056          ast_mutex_unlock(&pGkClient->Lock);
2057          ast_cond_signal(&pCallAdmInfo->call->gkWait);
2058          return OO_OK;
2059       }
2060       else
2061       {
2062          pNode = pNode->next;
2063       }
2064    }
2065    OOTRACEERR1("Error: Failed to process ACF as there is no corresponding "
2066                "pending call\n");
2067    ast_mutex_unlock(&pGkClient->Lock);
2068    return OO_OK;
2069 }
2070
2071
2072 int ooGkClientHandleAdmissionReject
2073    (ooGkClient *pGkClient, H225AdmissionReject *pAdmissionReject)
2074 {
2075    RasCallAdmissionInfo* pCallAdmInfo=NULL;
2076    unsigned int x, y;
2077    DListNode *pNode=NULL, *pNode1=NULL;
2078    OOH323CallData *call=NULL;
2079    OOTimer *pTimer = NULL;
2080
2081    ast_mutex_lock(&pGkClient->Lock);
2082
2083    /* Search call in pending calls list */
2084    for(x=0 ; x<pGkClient->callsPendingList.count; x++)
2085    {
2086       pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
2087       pCallAdmInfo = (RasCallAdmissionInfo*) pNode->data;
2088       if(pCallAdmInfo->requestSeqNum == pAdmissionReject->requestSeqNum)
2089          break;
2090       pNode = NULL;
2091       pCallAdmInfo = NULL;
2092    }
2093
2094    if(!pCallAdmInfo)
2095    {
2096       OOTRACEWARN2("Received admission reject with request number %d can not"
2097                    " be matched with any pending call.\n", 
2098                    pAdmissionReject->requestSeqNum);
2099       ast_mutex_unlock(&pGkClient->Lock);
2100       return OO_OK;
2101    }
2102    else{
2103       call = pCallAdmInfo->call;
2104       dListRemove(&pGkClient->callsPendingList, pNode);
2105       memFreePtr(&pGkClient->ctxt, pCallAdmInfo);
2106       memFreePtr(&pGkClient->ctxt, pNode);
2107    }
2108    ast_mutex_lock(&pCallAdmInfo->call->GkLock);
2109
2110    /* Delete ARQ timer */
2111    for(y=0; y<pGkClient->timerList.count; y++)
2112    {
2113      pNode1 =  dListFindByIndex(&pGkClient->timerList, y);
2114      pTimer = (OOTimer*)pNode1->data;
2115      if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_ARQ_TIMER)
2116      {
2117                if(((ooGkClientTimerCb*)pTimer->cbData)->pAdmInfo == 
2118                                                                  pCallAdmInfo)
2119                {
2120                   memFreePtr(&pGkClient->ctxt, pTimer->cbData);
2121                   ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, 
2122                                                                        pTimer);
2123                   OOTRACEDBGA1("Deleted ARQ Timer.\n");
2124                   break;
2125                }
2126      }
2127    }       
2128    OOTRACEINFO4("Admission Reject message received with reason code %d for "
2129                 "(%s, %s)\n", pAdmissionReject->rejectReason.t, call->callType,
2130                  call->callToken);
2131    
2132    call->callState = OO_CALL_CLEARED;
2133
2134    switch(pAdmissionReject->rejectReason.t)
2135    {
2136       case T_H225AdmissionRejectReason_calledPartyNotRegistered:
2137          call->callEndReason = OO_REASON_GK_NOCALLEDUSER;
2138          break;
2139       case T_H225AdmissionRejectReason_invalidPermission:
2140       case T_H225AdmissionRejectReason_requestDenied:
2141       case T_H225AdmissionRejectReason_undefinedReason:
2142          call->callEndReason = OO_REASON_GK_CLEARED;
2143          break;
2144       case T_H225AdmissionRejectReason_callerNotRegistered:
2145          call->callEndReason = OO_REASON_GK_NOCALLERUSER;
2146          break;
2147       case T_H225AdmissionRejectReason_exceedsCallCapacity:
2148       case T_H225AdmissionRejectReason_resourceUnavailable:
2149          call->callEndReason = OO_REASON_GK_NORESOURCES;
2150          break;
2151       case T_H225AdmissionRejectReason_noRouteToDestination:
2152       case T_H225AdmissionRejectReason_unallocatedNumber:
2153          call->callEndReason = OO_REASON_GK_UNREACHABLE;
2154          break;
2155       case T_H225AdmissionRejectReason_routeCallToGatekeeper:
2156       case T_H225AdmissionRejectReason_invalidEndpointIdentifier:
2157       case T_H225AdmissionRejectReason_securityDenial:
2158       case T_H225AdmissionRejectReason_qosControlNotSupported:
2159       case T_H225AdmissionRejectReason_incompleteAddress:
2160       case T_H225AdmissionRejectReason_aliasesInconsistent:
2161       case T_H225AdmissionRejectReason_routeCallToSCN:
2162       case T_H225AdmissionRejectReason_collectDestination:
2163       case T_H225AdmissionRejectReason_collectPIN:
2164       case T_H225AdmissionRejectReason_genericDataReason:
2165       case T_H225AdmissionRejectReason_neededFeatureNotSupported:
2166       case T_H225AdmissionRejectReason_securityErrors:
2167       case T_H225AdmissionRejectReason_securityDHmismatch:
2168       case T_H225AdmissionRejectReason_extElem1:
2169          call->callEndReason = OO_REASON_GK_CLEARED;
2170          break;
2171    }
2172
2173    ast_mutex_unlock(&pCallAdmInfo->call->GkLock);
2174    ast_mutex_unlock(&pGkClient->Lock);
2175    ast_cond_signal(&pCallAdmInfo->call->gkWait);
2176    return OO_OK;   
2177 }
2178
2179
2180 int ooGkClientSendIRR
2181    (ooGkClient *pGkClient, OOH323CallData *call)
2182 {
2183    int iRet = 0;
2184    H225RasMessage *pRasMsg=NULL;
2185    OOCTXT* pctxt;
2186    H225InfoRequestResponse *pIRR=NULL;
2187    H225TransportAddress_ipAddress *pIpAddressLocal =NULL, *pIpRasAddress,
2188                                    *pLocalAddr, *pRemoteAddr;
2189    H225TransportAddress *pTransportAddress;
2190    ooAliases *srcAliases=NULL;
2191    H225InfoRequestResponse_perCallInfo_element *perCallInfo = NULL;
2192    pctxt = &pGkClient->msgCtxt;
2193
2194    ast_mutex_lock(&pGkClient->Lock);
2195
2196    OOTRACEDBGA3("Building Info Request Resp for call (%s, %s)\n", 
2197                  call->callType, call->callToken);   
2198    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
2199    if(!pRasMsg)
2200    {
2201       OOTRACEERR3("Error:Memory - ooGkClientSendIRR - "
2202                   "pRasMsg(%s, %s)\n", call->callType, call->callToken);
2203       pGkClient->state = GkClientFailed;
2204       ast_mutex_unlock(&pGkClient->Lock);
2205       return OO_FAILED;
2206    }
2207    pRasMsg->t = T_H225RasMessage_infoRequestResponse;
2208    pIRR = (H225InfoRequestResponse*) memAlloc(pctxt, 
2209                                                  sizeof(H225InfoRequestResponse));
2210    if(!pIRR)
2211    {
2212       OOTRACEERR3("Error:Memory - ooGkClientSendIRR - "
2213                   "pIRR(%s, %s)\n", call->callType, call->callToken);
2214       memReset(pctxt);
2215       pGkClient->state = GkClientFailed;
2216       ast_mutex_unlock(&pGkClient->Lock);
2217       return OO_FAILED;
2218    }
2219    memset(pIRR, 0, sizeof(H225InfoRequestResponse));
2220    pRasMsg->u.infoRequestResponse = pIRR;
2221    
2222    /* Populate call signalling addresses */
2223    pIpAddressLocal = (H225TransportAddress_ipAddress*)memAlloc(pctxt, 
2224                                      sizeof(H225TransportAddress_ipAddress));
2225    pTransportAddress = (H225TransportAddress*) memAlloc(pctxt,
2226                                                  sizeof(H225TransportAddress));
2227    if(!pIpAddressLocal || !pTransportAddress)
2228    {
2229       OOTRACEERR1("Error:Failed to allocate memory for Call Signalling "
2230                   "Addresses of IRR message\n");
2231       memReset(pctxt);
2232       pGkClient->state = GkClientFailed;
2233       ast_mutex_unlock(&pGkClient->Lock);
2234       return OO_FAILED;
2235    }
2236    inet_pton(AF_INET, pGkClient->localRASIP, pIpAddressLocal->ip.data);
2237
2238    pIpAddressLocal->ip.numocts = 4;
2239    pIpAddressLocal->port = gH323ep.listenPort;
2240
2241    pTransportAddress->t = T_H225TransportAddress_ipAddress;
2242    pTransportAddress->u.ipAddress = pIpAddressLocal;
2243
2244    dListInit(&pIRR->callSignalAddress);
2245    dListAppend(pctxt, &pIRR->callSignalAddress,
2246                                        (void*)pTransportAddress);
2247
2248    /* Populate seq number */
2249    pIRR->requestSeqNum = pGkClient->requestSeqNum++;
2250    if(!pIRR->requestSeqNum)
2251       pIRR->requestSeqNum = pGkClient->requestSeqNum++;
2252
2253    pIpRasAddress = (H225TransportAddress_ipAddress*)memAlloc(pctxt, 
2254                                      sizeof(H225TransportAddress_ipAddress));
2255    if(!pIpRasAddress)
2256    {
2257       OOTRACEERR1("Error: Memory allocation for Ras Address of IRR message "
2258                   "failed\n");
2259       memReset(&pGkClient->msgCtxt);
2260       pGkClient->state = GkClientFailed;
2261       ast_mutex_unlock(&pGkClient->Lock);
2262       return OO_FAILED;
2263    }
2264
2265    pIpRasAddress->ip.numocts = 4;
2266    pIpRasAddress->port = pGkClient->localRASPort;
2267    inet_pton(AF_INET, pGkClient->localRASIP, pIpRasAddress->ip.data);
2268
2269    pIRR->rasAddress.u.ipAddress = pIpRasAddress;
2270    pIRR->rasAddress.t=T_H225TransportAddress_ipAddress; /* IPv4 address */
2271
2272    /* Pose as gateway or terminal as per config */
2273    if(gH323ep.isGateway)
2274       pIRR->endpointType.m.gatewayPresent = TRUE;
2275    else
2276       pIRR->endpointType.m.terminalPresent = TRUE;
2277
2278    pIRR->endpointType.m.nonStandardDataPresent=FALSE;
2279    pIRR->endpointType.m.vendorPresent=TRUE;
2280    ooGkClientFillVendor(pGkClient, &pIRR->endpointType.vendor);
2281
2282    /* Populate Endpoint Identifier */
2283    pIRR->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
2284    pIRR->endpointIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
2285                            sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
2286    if(!pIRR->endpointIdentifier.data)
2287    {
2288       OOTRACEERR3("Error:Memory -  ooGkClientSendIRR - "
2289                   "endpointIdentifier.data(%s, %s)\n", call->callType,
2290                   call->callToken);
2291       memReset(pctxt);
2292       pGkClient->state = GkClientFailed;
2293       ast_mutex_unlock(&pGkClient->Lock);
2294       return OO_FAILED;
2295    }
2296    memcpy((void*)pIRR->endpointIdentifier.data,
2297           (void*)pGkClient->endpointId.data,
2298           sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
2299
2300
2301    /* Populate call aliases */
2302    if(call->ourAliases) 
2303       srcAliases = call->ourAliases;
2304    else
2305       srcAliases = gH323ep.aliases; 
2306
2307    /* Populate Source Info */
2308    if(srcAliases)
2309    {
2310       iRet = ooPopulateAliasList(&pGkClient->msgCtxt, srcAliases,
2311                              &pIRR->endpointAlias, T_H225AliasAddress_h323_ID);
2312       if(OO_OK != iRet)
2313       {
2314          OOTRACEERR1("Error:Failed to populate source aliases -IRR message\n");
2315          memReset(pctxt);
2316          pGkClient->state = GkClientFailed;
2317          ast_mutex_unlock(&pGkClient->Lock);
2318          return OO_FAILED;
2319       }
2320    }
2321    pIRR->m.endpointAliasPresent = TRUE;
2322
2323    /* Populate need response & unsolicited */
2324    pIRR->needResponse = FALSE;
2325    pIRR->m.needResponsePresent = TRUE;
2326    pIRR->unsolicited = TRUE;
2327    pIRR->m.unsolicitedPresent = TRUE;
2328    
2329    /* Populate perCallInfo */
2330
2331    pIRR->m.perCallInfoPresent = TRUE;
2332
2333    perCallInfo = 
2334     (H225InfoRequestResponse_perCallInfo_element *)memAlloc(pctxt,
2335      sizeof(H225InfoRequestResponse_perCallInfo_element));
2336    memset(perCallInfo, 0, sizeof(H225InfoRequestResponse_perCallInfo_element));
2337
2338    if(!perCallInfo)
2339    {
2340       OOTRACEERR3("Error:Memory -  ooGkClientSendIRR - "
2341                   "perCallInfo for (%s, %s)\n", call->callType,
2342                   call->callToken);
2343       memReset(pctxt);
2344       pGkClient->state = GkClientFailed;
2345       ast_mutex_unlock(&pGkClient->Lock);
2346       return OO_FAILED;
2347    }
2348
2349    perCallInfo->m.originatorPresent = TRUE;
2350    perCallInfo->originator = (!strcmp(call->callType, "incoming")) ? FALSE : TRUE;
2351
2352    pLocalAddr = (H225TransportAddress_ipAddress*)memAlloc(pctxt,
2353                                      sizeof(H225TransportAddress_ipAddress));
2354    pRemoteAddr = (H225TransportAddress_ipAddress*) memAlloc(pctxt,
2355                                      sizeof(H225TransportAddress_ipAddress));
2356    if(!pLocalAddr || !pRemoteAddr)
2357    {
2358       OOTRACEERR1("Error:Failed to allocate memory for Call Signalling "
2359                   "Addresses of IRR message\n");
2360       memReset(pctxt);
2361       pGkClient->state = GkClientFailed;
2362       ast_mutex_unlock(&pGkClient->Lock);
2363       return OO_FAILED;
2364    }
2365    pLocalAddr->ip.numocts = 4;
2366    inet_pton(AF_INET, call->localIP, pLocalAddr->ip.data);
2367    pLocalAddr->port = (call->pH225Channel->port) ? call->pH225Channel->port : gH323ep.listenPort;
2368
2369    pRemoteAddr->ip.numocts = 4;
2370    inet_pton(AF_INET, call->remoteIP, pRemoteAddr->ip.data);
2371    pRemoteAddr->port = call->remotePort;
2372
2373    perCallInfo->callSignaling.m.sendAddressPresent = TRUE;
2374    perCallInfo->callSignaling.sendAddress.t = T_H225TransportAddress_ipAddress; 
2375    perCallInfo->callSignaling.m.recvAddressPresent = TRUE;
2376    perCallInfo->callSignaling.recvAddress.t = T_H225TransportAddress_ipAddress; 
2377
2378    if (!strcmp(call->callType, "incoming")) {
2379 // terminator
2380      perCallInfo->callSignaling.sendAddress.u.ipAddress = pRemoteAddr;
2381      perCallInfo->callSignaling.recvAddress.u.ipAddress = pLocalAddr;
2382    } else {
2383 // originator
2384      perCallInfo->callSignaling.sendAddress.u.ipAddress = pLocalAddr;
2385      perCallInfo->callSignaling.recvAddress.u.ipAddress = pRemoteAddr;
2386    }
2387
2388    /* Populate call Reference */
2389    perCallInfo->callReferenceValue = call->callReference;
2390    /* populate conferenceID */
2391    memcpy((void*)&perCallInfo->conferenceID, (void*)&call->confIdentifier,
2392                                          sizeof(H225ConferenceIdentifier));
2393    /* Populate call identifier */
2394    perCallInfo->m.callIdentifierPresent = TRUE;
2395    memcpy((void*)&perCallInfo->callIdentifier, (void*)&call->callIdentifier,
2396                                              sizeof(H225CallIdentifier));
2397    /* Populate call type & call model */
2398    perCallInfo->callType.t = T_H225CallType_pointToPoint;
2399    /* Add call model to message*/
2400    if(OO_TESTFLAG(call->flags, OO_M_GKROUTED))
2401       perCallInfo->callModel.t = T_H225CallModel_gatekeeperRouted;
2402    else
2403       perCallInfo->callModel.t = T_H225CallModel_direct;
2404
2405    /* Populate usage info */
2406    if (call->alertingTime) {
2407      perCallInfo->usageInformation.m.alertingTimePresent = TRUE;
2408      perCallInfo->usageInformation.alertingTime = call->alertingTime;
2409    }
2410    if (call->connectTime) {
2411     perCallInfo->usageInformation.m.connectTimePresent = TRUE;
2412     perCallInfo->usageInformation.connectTime = call->connectTime;
2413    }
2414    perCallInfo->usageInformation.m.endTimePresent = FALSE;
2415    perCallInfo->m.usageInformationPresent = TRUE;
2416    
2417    dListInit(&pIRR->perCallInfo);
2418    dListAppend(pctxt, &pIRR->perCallInfo,
2419                                        (void*)perCallInfo);
2420
2421    iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
2422    if(iRet != OO_OK)
2423    {
2424       OOTRACEERR1("Error:Failed to send IRR message\n");
2425       memReset(pctxt);
2426       pGkClient->state = GkClientFailed;
2427       ast_mutex_unlock(&pGkClient->Lock);
2428       return OO_FAILED;
2429    }
2430    OOTRACEINFO3("IRR message sent for (%s, %s)\n", 
2431                  call->callType, call->callToken);
2432    memReset(pctxt);
2433     
2434    ast_mutex_unlock(&pGkClient->Lock);
2435    return OO_OK;
2436 }
2437
2438 /**
2439  * This function is invoked to request call disengage to gatekeeper. 
2440  * 
2441  * @param   szCallToken    Call token.     
2442  *
2443  * @return  Completion status - 0 on success, -1 on failure
2444  */
2445
2446 int ooGkClientSendDisengageRequest(ooGkClient *pGkClient, OOH323CallData *call)
2447 {
2448    int iRet = 0;   
2449    unsigned int x;
2450    H225RasMessage *pRasMsg=NULL;
2451    OOCTXT *pctxt = NULL;
2452    DListNode *pNode = NULL;
2453    H225DisengageRequest * pDRQ = NULL;
2454    RasCallAdmissionInfo* pCallAdmInfo=NULL;
2455    pctxt = &pGkClient->msgCtxt;
2456
2457    ast_mutex_lock(&pGkClient->Lock);
2458
2459    OOTRACEINFO3("Sending disengage Request for  call. (%s, %s)\n",
2460                  call->callType, call->callToken);
2461
2462    pRasMsg = (H225RasMessage*)memAlloc(pctxt, sizeof(H225RasMessage));
2463    if(!pRasMsg)
2464    {
2465       OOTRACEERR1("Error: Memory allocation for DRQ RAS message failed\n");
2466       pGkClient->state = GkClientFailed;
2467       ast_mutex_unlock(&pGkClient->Lock);
2468       return OO_FAILED;
2469    }
2470
2471    pRasMsg->t = T_H225RasMessage_disengageRequest;
2472    pDRQ = (H225DisengageRequest*) memAlloc(pctxt, 
2473                                                sizeof(H225DisengageRequest));
2474    if(!pDRQ)
2475    {
2476       OOTRACEERR1("Error: Failed to allocate memory for DRQ message\n");
2477       memReset(pctxt);
2478       pGkClient->state = GkClientFailed;
2479       ast_mutex_unlock(&pGkClient->Lock);
2480       return OO_FAILED;
2481    }
2482
2483    memset(pDRQ, 0, sizeof(H225DisengageRequest));
2484    pRasMsg->u.disengageRequest = pDRQ;
2485    
2486    pDRQ->requestSeqNum = pGkClient->requestSeqNum++;
2487    if(!pDRQ->requestSeqNum )
2488       pDRQ->requestSeqNum = pGkClient->requestSeqNum++;
2489    
2490    
2491    pDRQ->endpointIdentifier.nchars = pGkClient->endpointId.nchars;
2492    pDRQ->endpointIdentifier.data = (ASN116BITCHAR*)memAlloc(pctxt,
2493                            sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
2494    if(!pDRQ->endpointIdentifier.data)
2495    {
2496       OOTRACEERR1("Error: Failed to allocate memory for EndPoint Id in DRQ "
2497                   "message.\n");
2498       memReset(pctxt);
2499       pGkClient->state = GkClientFailed;
2500       ast_mutex_unlock(&pGkClient->Lock);
2501       return OO_FAILED;
2502    }
2503    memcpy((void*)pDRQ->endpointIdentifier.data, 
2504                  (void*)pGkClient->endpointId.data, 
2505                  sizeof(ASN116BITCHAR)*pGkClient->endpointId.nchars);
2506
2507    memcpy((void*)&pDRQ->conferenceID, (void*)&call->confIdentifier,
2508                                          sizeof(H225ConferenceIdentifier));
2509
2510    pDRQ->callReferenceValue = call->callReference;
2511    
2512    pDRQ->disengageReason.t = T_H225DisengageReason_normalDrop;
2513
2514    pDRQ->m.answeredCallPresent = 1;
2515    if(!strcmp(call->callType, "incoming"))
2516       pDRQ->answeredCall = 1;
2517    else
2518       pDRQ->answeredCall = 0;
2519
2520    pDRQ->m.callIdentifierPresent = 1;
2521    memcpy((void*)&pDRQ->callIdentifier, (void*)&call->callIdentifier,
2522                                              sizeof(H225CallIdentifier));
2523    if (pGkClient->gkId.nchars) {
2524     pDRQ->m.gatekeeperIdentifierPresent = 1;
2525     pDRQ->gatekeeperIdentifier.nchars = pGkClient->gkId.nchars;
2526     pDRQ->gatekeeperIdentifier.data = (ASN116BITCHAR*)memAlloc
2527                        (pctxt, pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
2528     if(!pDRQ->gatekeeperIdentifier.data)
2529     {
2530       OOTRACEERR1("Error:Failed to allocate memory for GKId in DRQ.\n");
2531       memReset(pctxt);
2532       pGkClient->state = GkClientFailed;
2533       ast_mutex_unlock(&pGkClient->Lock);
2534       return OO_FAILED;
2535     }
2536     memcpy(pDRQ->gatekeeperIdentifier.data, pGkClient->gkId.data, 
2537                                 pGkClient->gkId.nchars*sizeof(ASN116BITCHAR));
2538    }
2539
2540    pDRQ->m.terminationCausePresent = 1;
2541    pDRQ->terminationCause.t = T_H225CallTerminationCause_releaseCompleteCauseIE;
2542    pDRQ->terminationCause.u.releaseCompleteCauseIE = 
2543       (H225CallTerminationCause_releaseCompleteCauseIE*)memAlloc(pctxt,
2544       sizeof(H225CallTerminationCause_releaseCompleteCauseIE));
2545    if(!pDRQ->terminationCause.u.releaseCompleteCauseIE)
2546    {
2547       OOTRACEERR1("Error: Failed to allocate memory for cause ie in DRQ.\n");
2548       memReset(pctxt);
2549       pGkClient->state = GkClientFailed;
2550       ast_mutex_unlock(&pGkClient->Lock);
2551       return OO_FAILED;
2552    }
2553    pDRQ->terminationCause.u.releaseCompleteCauseIE->numocts = 
2554                                                          strlen("Call Ended");
2555    strcpy((char *)pDRQ->terminationCause.u.releaseCompleteCauseIE->data, "Call Ended");
2556
2557    /* populate usage info */
2558
2559    /* Populate usage info */
2560    if (call->alertingTime) {
2561      pDRQ->usageInformation.m.alertingTimePresent = TRUE;
2562      pDRQ->usageInformation.alertingTime = call->alertingTime;
2563    }
2564    if (call->connectTime) {
2565     pDRQ->usageInformation.m.connectTimePresent = TRUE;
2566     pDRQ->usageInformation.connectTime = call->connectTime;
2567    }
2568    pDRQ->usageInformation.m.endTimePresent = TRUE;
2569    if (call->endTime)
2570     pDRQ->usageInformation.endTime = call->endTime;
2571    else
2572     pDRQ->usageInformation.endTime = time(NULL);
2573    pDRQ->m.usageInformationPresent = TRUE;
2574
2575    iRet = ooGkClientSendMsg(pGkClient, pRasMsg);
2576    if(iRet != OO_OK)
2577    {
2578       OOTRACEERR1("Error: Failed to send DRQ message\n");
2579       pGkClient->state = GkClientFailed;
2580    }
2581    
2582
2583
2584    /* Search call in admitted calls list */
2585    for(x=0 ; x<pGkClient->callsAdmittedList.count ; x++)
2586    {
2587       pNode = (DListNode*)dListFindByIndex(&pGkClient->callsAdmittedList, x);
2588       pCallAdmInfo = (RasCallAdmissionInfo*) pNode->data;
2589       if(pCallAdmInfo->call->callReference == call->callReference)
2590       {
2591          dListRemove( &pGkClient->callsAdmittedList, pNode);
2592          memFreePtr(&pGkClient->ctxt, pNode->data);
2593          memFreePtr(&pGkClient->ctxt, pNode);
2594          break;
2595       }
2596    }
2597    ast_mutex_unlock(&pGkClient->Lock);
2598    return iRet;
2599 }     
2600
2601 int ooGkClientHandleDisengageConfirm
2602    (ooGkClient *pGkClient, H225DisengageConfirm *pDCF)
2603 {
2604    OOTRACEINFO1("Received disengage confirm\n");
2605    return OO_OK;
2606 }
2607
2608 int ooGkClientRRQTimerExpired(void*pdata)
2609 {
2610    int ret=0;
2611    ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
2612    ooGkClient *pGkClient = cbData->pGkClient;
2613    OOTRACEDBGA1("Gatekeeper client RRQ timer expired.\n");
2614    
2615    if(pGkClient->rrqRetries < OO_MAX_RRQ_RETRIES)
2616    {
2617       ret = ooGkClientSendRRQ(pGkClient, 0);      
2618       if(ret != OO_OK)
2619       {
2620          OOTRACEERR1("Error:Failed to send RRQ message\n");
2621          
2622          return OO_FAILED;
2623       }
2624       pGkClient->rrqRetries++;
2625       memFreePtr(&pGkClient->ctxt, cbData);
2626       return OO_OK;
2627    }
2628    memFreePtr(&pGkClient->ctxt, cbData);
2629    OOTRACEERR1("Error:Failed to register with gatekeeper\n");
2630    pGkClient->state = GkClientUnregistered;
2631
2632
2633 /* Create timer to re-register after default timeout */
2634 /* network failure is one of cases here */
2635
2636    ast_mutex_lock(&pGkClient->Lock);
2637
2638    cbData = (ooGkClientTimerCb*) memAlloc
2639                                 (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
2640    if(!cbData)
2641    {
2642       OOTRACEERR1("Error:Failed to allocate memory to RRQ timer callback\n");
2643       pGkClient->state = GkClientFailed;
2644       ast_mutex_unlock(&pGkClient->Lock);
2645       return OO_FAILED;
2646    }
2647
2648
2649    cbData->timerType = OO_RRQ_TIMER;
2650    cbData->pGkClient = pGkClient;
2651    if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
2652                      &ooGkClientRRQTimerExpired, pGkClient->regTimeout,
2653                      cbData, FALSE))
2654    {
2655       OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
2656       memFreePtr(&pGkClient->ctxt, cbData);
2657       pGkClient->state = GkClientFailed;
2658       ast_mutex_unlock(&pGkClient->Lock);
2659       return OO_FAILED;
2660    }
2661
2662 /* clear rrq count for re-register after regTimeout */
2663    pGkClient->rrqRetries = 0;
2664
2665    ast_mutex_unlock(&pGkClient->Lock);
2666
2667    return OO_FAILED;
2668 }
2669
2670 int ooGkClientGRQTimerExpired(void* pdata)
2671 {
2672    int ret=0;
2673    ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
2674    ooGkClient *pGkClient = cbData->pGkClient;
2675
2676    OOTRACEDBGA1("Gatekeeper client GRQ timer expired.\n");
2677
2678    memFreePtr(&pGkClient->ctxt, cbData);   
2679
2680    if(pGkClient->grqRetries < OO_MAX_GRQ_RETRIES)
2681    {
2682       ret = ooGkClientSendGRQ(pGkClient);      
2683       if(ret != OO_OK)
2684       {
2685          OOTRACEERR1("Error:Failed to send GRQ message\n");
2686          pGkClient->state = GkClientFailed;
2687          return OO_FAILED;
2688       }
2689       pGkClient->grqRetries++;
2690       return OO_OK;
2691    }
2692
2693    OOTRACEERR1("Error:Gatekeeper could not be found\n");
2694    pGkClient->state = GkClientUnregistered;
2695 /* setup timer to re-send grq after timeout */
2696
2697    ast_mutex_lock(&pGkClient->Lock);
2698    cbData = (ooGkClientTimerCb*) memAlloc
2699                                (&pGkClient->ctxt, sizeof(ooGkClientTimerCb));
2700    if(!cbData)
2701    {
2702       OOTRACEERR1("Error:Failed to allocate memory to GRQ timer callback\n");
2703       pGkClient->state = GkClientFailed;
2704       ast_mutex_unlock(&pGkClient->Lock);
2705       return OO_FAILED;
2706    }
2707    cbData->timerType = OO_GRQ_TIMER;
2708    cbData->pGkClient = pGkClient;
2709    if(!ooTimerCreate(&pGkClient->ctxt, &pGkClient->timerList,
2710                      &ooGkClientGRQTimerExpired, pGkClient->grqTimeout,
2711                      cbData, FALSE))
2712    {
2713       OOTRACEERR1("Error:Unable to create GRQ timer.\n ");
2714       memFreePtr(&pGkClient->ctxt, cbData);
2715       pGkClient->state = GkClientFailed;
2716       ast_mutex_unlock(&pGkClient->Lock);
2717       return OO_FAILED;
2718    }
2719  
2720 /* clear grq counter */
2721
2722    pGkClient->grqRetries = 0;
2723    ast_mutex_unlock(&pGkClient->Lock);
2724
2725    return OO_FAILED;
2726 }
2727    
2728 int ooGkClientREGTimerExpired(void *pdata)
2729 {
2730    int ret=0;
2731    ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
2732    ooGkClient *pGkClient = cbData->pGkClient;
2733    OOTRACEDBGA1("Gatekeeper client additive registration timer expired\n");
2734    memFreePtr(&pGkClient->ctxt, cbData);   
2735    ret = ooGkClientSendRRQ(pGkClient, TRUE);      
2736    if(ret != OO_OK)
2737    {
2738       OOTRACEERR1("Error:Failed to send Additive RRQ message\n");
2739       pGkClient->state = GkClientFailed;
2740       return OO_FAILED;
2741    }
2742    return OO_OK;
2743 }
2744
2745 int ooGkClientARQTimerExpired(void* pdata)
2746 {
2747    int ret=0;
2748    ooGkClientTimerCb *cbData = (ooGkClientTimerCb*)pdata;
2749    ooGkClient *pGkClient = cbData->pGkClient;
2750    RasCallAdmissionInfo *pAdmInfo = cbData->pAdmInfo;
2751
2752    OOTRACEDBGA1("Gatekeeper client ARQ timer expired.\n");
2753    memFreePtr(&pGkClient->ctxt, cbData);   
2754
2755    if(!pAdmInfo)
2756     return OO_OK;
2757
2758    if(pAdmInfo->retries < OO_MAX_ARQ_RETRIES)
2759    {
2760       ret = ooGkClientSendAdmissionRequest(pGkClient, pAdmInfo->call, TRUE);      
2761       if(ret != OO_OK)
2762       {
2763          OOTRACEERR1("Error:Failed to send ARQ message\n");
2764          return OO_FAILED;
2765       }
2766       pAdmInfo->retries++;
2767       return OO_OK;
2768    }
2769
2770    OOTRACEERR1("Error:Gatekeeper not responding to ARQ\n");
2771    pGkClient->state = GkClientGkErr;
2772    return OO_FAILED;
2773 }
2774
2775 int ooGkClientCleanCall(ooGkClient *pGkClient, OOH323CallData *call)
2776 {
2777    unsigned int x=0;
2778    DListNode *pNode=NULL;
2779    OOTimer *pTimer;
2780    ooGkClientTimerCb *cbData=NULL;
2781    RasCallAdmissionInfo *pAdmInfo = NULL;
2782
2783    ast_mutex_lock(&pGkClient->Lock);
2784
2785
2786    for(x=0; x<pGkClient->callsAdmittedList.count; x++)
2787    {
2788       pNode = dListFindByIndex(&pGkClient->callsAdmittedList, x);
2789       pAdmInfo = (RasCallAdmissionInfo*)pNode->data;
2790       if(pAdmInfo->call->callReference == call->callReference)
2791       {
2792          dListRemove(&pGkClient->callsAdmittedList, pNode);
2793          memFreePtr(&pGkClient->ctxt, pAdmInfo);
2794          memFreePtr(&pGkClient->ctxt, pNode);
2795          break;
2796       }
2797    }
2798
2799
2800    for(x=0; x<pGkClient->timerList.count; x++)
2801    {
2802       pNode = dListFindByIndex(&pGkClient->timerList, x);
2803       pTimer = (OOTimer*)pNode->data;
2804       cbData = (ooGkClientTimerCb*)pTimer->cbData;
2805       if(cbData->timerType & OO_ARQ_TIMER &&
2806          cbData->pAdmInfo->call->callReference == call->callReference)
2807       {
2808          memFreePtr(&pGkClient->ctxt, pTimer->cbData);
2809          ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, pTimer);
2810          break;
2811       }
2812    }
2813
2814    for(x=0; x<pGkClient->callsPendingList.count; x++)
2815    {
2816       pNode = dListFindByIndex(&pGkClient->callsPendingList, x);
2817       pAdmInfo = (RasCallAdmissionInfo*)pNode->data;
2818       if(pAdmInfo->call->callReference == call->callReference)
2819       {
2820          dListRemove(&pGkClient->callsPendingList, pNode);
2821          memFreePtr(&pGkClient->ctxt, pAdmInfo);
2822          memFreePtr(&pGkClient->ctxt, pNode);
2823          break;
2824       }
2825    }
2826
2827    ast_mutex_unlock(&pGkClient->Lock);
2828    return OO_OK;
2829 }
2830
2831 /*
2832  * TODO: In case of GkErr, if GkMode is DiscoverGatekeeper,
2833  *       need to cleanup gkrouted calls, and discover another
2834  *       gatekeeper.
2835  * Note: This function returns OO_FAILED, when we can not recover from
2836  *       the failure.
2837  */
2838 int ooGkClientHandleClientOrGkFailure(ooGkClient *pGkClient)
2839 {
2840    if(pGkClient->state == GkClientFailed)
2841    {
2842       OOTRACEERR1("Error: Internal Failure in GkClient. Closing "
2843                   "GkClient\n");
2844       ooGkClientDestroy();
2845       return OO_FAILED;
2846    }
2847    else if(pGkClient->state == GkClientGkErr) {
2848       OOTRACEERR1("Error: Gatekeeper error. Either Gk not responding or "
2849                   "Gk sending invalid messages\n");
2850       if(pGkClient->gkMode == RasUseSpecificGatekeeper)
2851       {
2852          OOTRACEERR1("Error: Gatekeeper error detected. Closing GkClient as "
2853                      "Gk mode is UseSpecifcGatekeeper\n");
2854          ooGkClientDestroy();
2855          return OO_FAILED;
2856       }
2857       else{
2858          OOTRACEERR1("Error: Gatekeeper error detected. Closing GkClient. NEED"
2859                     " to implement recovery by rediscovering another gk\n");
2860          ooGkClientDestroy();
2861          return OO_FAILED;
2862       }
2863    }
2864
2865    return OO_FAILED;
2866 }
2867
2868 /**
2869  * TODO: This fuction might not work properly in case of additive registrations
2870  * For example we registrered 10 aliases and gatekeeper accepted 8 of them.
2871  * Now we want to register another two new aliases(not out of those first 10).
2872  * Gk responds with RCF with empty terminalAlias field thus indicating both 
2873  * the aliases were accepted. If this function is called, it will even mark
2874  * the earlier two unregistered aliases as registered. We will have to
2875  * maintain a separete list of aliases being sent in RRQ for this.
2876  */
2877 int ooGkClientUpdateRegisteredAliases
2878    (ooGkClient *pGkClient, H225_SeqOfH225AliasAddress *pAddresses, 
2879     OOBOOL registered)
2880 {
2881    int i=0, j, k;
2882    DListNode* pNode=NULL;
2883    ooAliases *pAlias=NULL;
2884    H225AliasAddress *pAliasAddress=NULL;
2885    H225TransportAddress *pTransportAddrss=NULL;
2886    char value[MAXFILENAME];
2887    OOBOOL bAdd = FALSE;
2888
2889    if(!pAddresses)
2890    {
2891      /* All aliases registered/unregistsred */
2892       pAlias = gH323ep.aliases;
2893       
2894       while(pAlias)
2895       {
2896          pAlias->registered = registered?TRUE:FALSE;
2897          pAlias = pAlias->next;
2898       }
2899       return OO_OK;
2900    }
2901
2902    /* Mark aliases as registered/unregistered*/
2903    if(pAddresses->count<=0)
2904       return OO_FAILED;
2905
2906    for(i=0; i<(int)pAddresses->count; i++)
2907    {
2908       pNode = dListFindByIndex (pAddresses, i);
2909       if(!pNode)
2910       {
2911          OOTRACEERR1("Error:Invalid alias list passed to "
2912                      "ooGkClientUpdateRegisteredAliases\n");
2913          continue;
2914       }
2915       pAliasAddress = (H225AliasAddress*)pNode->data;
2916       
2917       if(!pAliasAddress){
2918          OOTRACEERR1("Error:Invalid alias list passed to "
2919                      "ooGkClientUpdateRegisteredAliases\n");
2920          continue;
2921       }
2922
2923       switch(pAliasAddress->t)
2924       {
2925       case T_H225AliasAddress_dialedDigits:
2926          pAlias = ooH323GetAliasFromList(gH323ep.aliases, 
2927                                           T_H225AliasAddress_dialedDigits, 
2928                                         (char*)pAliasAddress->u.dialedDigits);
2929          if(pAlias)
2930          {
2931             pAlias->registered = registered?TRUE:FALSE;
2932          }
2933          else{
2934             bAdd = registered?TRUE:FALSE;
2935          }
2936          break;
2937       case T_H225AliasAddress_h323_ID:
2938          for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars && (k<MAXFILENAME-1); j++)
2939          {
2940             if(pAliasAddress->u.h323_ID.data[j] < 256)
2941             {
2942                value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2943             }
2944          }
2945          value[k] = '\0';
2946          pAlias = ooH323GetAliasFromList(gH323ep.aliases, 
2947                                          T_H225AliasAddress_h323_ID, 
2948                                           value);
2949          if(pAlias)
2950          {
2951             pAlias->registered = registered?TRUE:FALSE;
2952          }
2953          else{
2954             bAdd = registered?TRUE:FALSE;
2955          }
2956          break;
2957       case T_H225AliasAddress_url_ID:
2958          pAlias = ooH323GetAliasFromList(gH323ep.aliases, 
2959                                          T_H225AliasAddress_url_ID, 
2960                                        (char*)pAliasAddress->u.url_ID);
2961          if(pAlias)
2962          {
2963             pAlias->registered = registered?TRUE:FALSE;
2964          }
2965          else{
2966             bAdd = registered?TRUE:FALSE;
2967          }
2968          break;
2969       case T_H225AliasAddress_transportID:
2970          pTransportAddrss = pAliasAddress->u.transportID;
2971          if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
2972          {
2973             OOTRACEERR1("Error:Alias transportID not IP address\n");
2974             break;
2975          }
2976          
2977          sprintf(value, "%d.%d.%d.%d:%d", 
2978                           pTransportAddrss->u.ipAddress->ip.data[0],
2979                           pTransportAddrss->u.ipAddress->ip.data[1],
2980                           pTransportAddrss->u.ipAddress->ip.data[2],
2981                           pTransportAddrss->u.ipAddress->ip.data[3],
2982                           pTransportAddrss->u.ipAddress->port);
2983
2984          pAlias = ooH323GetAliasFromList(gH323ep.aliases, 
2985                                          T_H225AliasAddress_transportID, 
2986                                          value);
2987          if(pAlias)
2988          {
2989             pAlias->registered = registered?TRUE:FALSE;
2990          }
2991          else{
2992             bAdd = registered?TRUE:FALSE;
2993          }
2994          break;
2995       case T_H225AliasAddress_email_ID:
2996          pAlias = ooH323GetAliasFromList(gH323ep.aliases, 
2997                                          T_H225AliasAddress_email_ID, 
2998                                        (char*) pAliasAddress->u.email_ID);
2999          if(pAlias)
3000          {
3001             pAlias->registered = registered?TRUE:FALSE;
3002          }
3003          else{
3004             bAdd = registered?TRUE:FALSE;
3005          }
3006          break;
3007       default:
3008          OOTRACEERR1("Error:Unhandled alias type found in registered "
3009                      "aliases\n");
3010       }
3011       if(bAdd)
3012       {
3013          pAlias = ooH323AddAliasToList(&gH323ep.aliases, 
3014                                            &gH323ep.ctxt, pAliasAddress);
3015          if(pAlias){
3016             pAlias->registered = registered?TRUE:FALSE;
3017          }
3018          else{
3019             OOTRACEERR2("Warning:Could not add registered alias of "
3020                         "type %d to list.\n", pAliasAddress->t);
3021          }
3022          bAdd = FALSE;
3023       }
3024       pAlias = NULL;
3025    }
3026    return OO_OK;
3027 }