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