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