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