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