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