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