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