Fix warning of Coverity Static analysis, change H225ProtocolIdentifier
[asterisk/asterisk.git] / addons / ooh323c / src / ooh323.c
1 /*
2  * Copyright (C) 2004-2005 by Objective Systems, Inc.
3  *
4  * This software is furnished under an open source license and may be 
5  * used and copied only in accordance with the terms of this license. 
6  * The text of the license may generally be found in the root 
7  * directory of this installation in the COPYING file.  It 
8  * can also be viewed online at the following URL:
9  *
10  *   http://www.obj-sys.com/open/license.html
11  *
12  * Any redistributions of this file including modified versions must 
13  * maintain this copyright notice.
14  *
15  *****************************************************************************/
16
17 #include "asterisk.h"
18 #include "asterisk/lock.h"
19 #include "asterisk/time.h"
20 #include <time.h>
21
22 #include "ootypes.h"
23 #include "ooq931.h"
24 #include "ootrace.h"
25 #include "oochannels.h"
26 #include "ooh245.h"
27 #include "ooCalls.h"
28 #include "printHandler.h"
29 #include "ooh323.h"
30 #include "ooh323ep.h"
31 #include "ooGkClient.h"
32 #include "ooTimer.h"
33
34 /** Global endpoint structure */
35 extern OOH323EndPoint gH323ep;
36
37 int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility);
38 int ooOnReceivedReleaseComplete(OOH323CallData *call, Q931Message *q931Msg);
39 int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg);
40 int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg);
41 int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg);
42 int ooHandleDisplayIE(OOH323CallData *call, Q931Message *q931Msg);
43 int ooHandleH2250ID (OOH323CallData *call, H225ProtocolIdentifier* protocolIdentifier);
44
45 int ooHandleDisplayIE(OOH323CallData *call, Q931Message *q931Msg) {
46    Q931InformationElement* pDisplayIE;
47
48    /* check for display ie */
49    pDisplayIE = ooQ931GetIE(q931Msg, Q931DisplayIE);
50    if(pDisplayIE) {
51       if (call->remoteDisplayName)
52         memFreePtr(call->pctxt, call->remoteDisplayName);
53       call->remoteDisplayName = (char *) memAllocZ(call->pctxt, 
54                                  pDisplayIE->length*sizeof(ASN1OCTET)+1);
55       strncpy(call->remoteDisplayName, (char *)pDisplayIE->data, pDisplayIE->length*sizeof(ASN1OCTET));
56    }
57
58    return OO_OK;
59 }
60
61 int ooHandleH2250ID (OOH323CallData *call, H225ProtocolIdentifier* protocolIdentifier) {
62    if (!call->h225version && (protocolIdentifier->numids >= 6) &&
63         (protocolIdentifier->subid[3] == 2250)) {
64         call->h225version = protocolIdentifier->subid[5];
65         OOTRACEDBGC4("Extract H.225 remote version, it's %d, (%s, %s)\n", call->h225version, 
66                                                 call->callType, call->callToken);
67
68    }
69    return OO_OK;
70 }
71
72 int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
73 {
74    H245OpenLogicalChannel* olc;
75    ASN1OCTET msgbuf[MAXMSGLEN];
76    ooLogicalChannel * pChannel = NULL;
77    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
78    int i=0, ret=0;
79
80    /* Handle fast-start */
81    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART))
82    {
83       if(facility->m.fastStartPresent)
84       {
85          /* For printing the decoded message to log, initialize handler. */
86          initializePrintHandler(&printHandler, "FastStart Elements");
87
88          /* Set print handler */
89          setEventHandler (call->pctxt, &printHandler);
90
91          for(i=0; i<(int)facility->fastStart.n; i++)
92          {
93             olc = NULL;
94
95             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
96                                               sizeof(H245OpenLogicalChannel));
97             if(!olc)
98             {
99                OOTRACEERR3("ERROR:Memory - ooHandleFastStart - olc"
100                            "(%s, %s)\n", call->callType, call->callToken);
101                /*Mark call for clearing */
102                if(call->callState < OO_CALL_CLEAR)
103                {
104                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
105                   call->callState = OO_CALL_CLEAR;
106                }
107                return OO_FAILED;
108             }
109             memset(olc, 0, sizeof(H245OpenLogicalChannel));
110             memcpy(msgbuf, facility->fastStart.elem[i].data, 
111                                     facility->fastStart.elem[i].numocts);
112             setPERBuffer(call->pctxt, msgbuf, 
113                          facility->fastStart.elem[i].numocts, 1);
114             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
115             if(ret != ASN_OK)
116             {
117                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
118                            "(%s, %s)\n", call->callType, call->callToken);
119                /* Mark call for clearing */
120                if(call->callState < OO_CALL_CLEAR)
121                {
122                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
123                   call->callState = OO_CALL_CLEAR;
124                }
125                return OO_FAILED;
126             }
127
128             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
129
130             pChannel = ooFindLogicalChannelByOLC(call, olc);
131             if(!pChannel)
132             {
133                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
134                            "(%s, %s)\n",
135                             olc->forwardLogicalChannelNumber, call->callType, 
136                             call->callToken);
137                return OO_FAILED;
138             }
139             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
140             {
141                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
142                             "Number from %d to %d (%s, %s)\n", 
143                             pChannel->channelNo, 
144                             olc->forwardLogicalChannelNumber, call->callType, 
145                             call->callToken);
146                pChannel->channelNo = olc->forwardLogicalChannelNumber;
147             }
148             if(!strcmp(pChannel->dir, "transmit"))
149             {
150
151                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
152                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
153                {
154                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
155                               "channel %d (%s, %s)\n", 
156                               olc->forwardLogicalChannelNumber, call->callType,
157                               call->callToken);
158                   continue;
159                }
160             
161                /* Extract the remote media endpoint address */
162                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
163                if(!h2250lcp)
164                {
165                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
166                               "forward Logical Channel Parameters found. "
167                               "(%s, %s)\n", call->callType, call->callToken);
168                   return OO_FAILED;
169                }
170                if(!h2250lcp->m.mediaChannelPresent)
171                {
172                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
173                               "reverse media channel information found."
174                               "(%s, %s)\n", call->callType, call->callToken);
175                   return OO_FAILED;
176                }
177                ret = ooGetIpPortFromH245TransportAddress(call, 
178                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
179                                    &pChannel->remoteMediaPort);
180                
181                if(ret != OO_OK)
182                {
183                 if(call->callState < OO_CALL_CLEAR)
184                 {
185                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
186                   call->callState = OO_CALL_CLEAR;
187                 }
188                   OOTRACEERR3("ERROR:Unsupported media channel address type "
189                               "(%s, %s)\n", call->callType, call->callToken);
190                   return OO_FAILED;
191                }
192        
193                if(!pChannel->chanCap->startTransmitChannel)
194                {
195                   OOTRACEERR3("ERROR:No callback registered to start transmit "
196                               "channel (%s, %s)\n",call->callType, 
197                               call->callToken);
198                   return OO_FAILED;
199                }
200                pChannel->chanCap->startTransmitChannel(call, pChannel);
201             }
202             /* Mark the current channel as established and close all other 
203                logical channels with same session id and in same direction.
204             */
205             ooOnLogicalChannelEstablished(call, pChannel);
206          }
207          finishPrint();
208          removeEventHandler(call->pctxt);
209          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
210       }
211       
212    }
213
214    if(facility->m.h245AddressPresent)
215    {
216       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
217       {
218          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
219          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
220                       "provided in facility message (%s, %s)\n", 
221                       call->callType, call->callToken);
222       }
223       ret = ooH323GetIpPortFromH225TransportAddress(call, 
224                                   &facility->h245Address, call->remoteIP,
225                                   &call->remoteH245Port);
226       if(ret != OO_OK)
227       {
228          OOTRACEERR3("Error: Unknown H245 address type in received "
229                      "Facility message (%s, %s)", call->callType, 
230                      call->callToken);
231          /* Mark call for clearing */
232          if(call->callState < OO_CALL_CLEAR)
233          {
234             call->callEndReason = OO_REASON_INVALIDMESSAGE;
235             call->callState = OO_CALL_CLEAR;
236          }
237          return OO_FAILED;
238       }
239       if(call->remoteH245Port != 0 && !call->pH245Channel) {
240       /* Create an H.245 connection. 
241       */
242        if(ooCreateH245Connection(call)== OO_FAILED)
243        {
244          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
245                      call->callType, call->callToken);
246
247          if(call->callState < OO_CALL_CLEAR)
248          {
249             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
250             call->callState = OO_CALL_CLEAR;
251          }
252          return OO_FAILED;
253        }
254       }
255    } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
256         if (call->h225version >= 4) {
257                 ret =ooSendTCSandMSD(call);
258         }
259         if (ret != OO_OK)
260                 return ret;
261    }
262    return OO_OK;
263 }
264
265 int ooOnReceivedReleaseComplete(OOH323CallData *call, Q931Message *q931Msg)
266 {
267    int ret = OO_OK;
268    H225ReleaseComplete_UUIE * releaseComplete = NULL;
269    ASN1UINT i;
270    DListNode *pNode = NULL;
271    OOTimer *pTimer = NULL;
272    unsigned reasonCode=T_H225ReleaseCompleteReason_undefinedReason;
273    enum Q931CauseValues cause= Q931ErrorInCauseIE;
274
275    if(q931Msg->causeIE)
276    {
277       cause = q931Msg->causeIE->data[1];
278       /* Get rid of the extension bit.For more info, check ooQ931SetCauseIE */
279       cause = cause & 0x7f; 
280       OOTRACEDBGA4("Cause of Release Complete is %x. (%s, %s)\n", cause, 
281                                              call->callType, call->callToken);
282    }
283
284    /* Remove session timer, if active*/
285    for(i = 0; i<call->timerList.count; i++)
286    {
287       pNode = dListFindByIndex(&call->timerList, i);
288       pTimer = (OOTimer*)pNode->data;
289       if(((ooTimerCallback*)pTimer->cbData)->timerType & 
290                                                    OO_SESSION_TIMER)
291       {
292          memFreePtr(call->pctxt, pTimer->cbData);
293          ooTimerDelete(call->pctxt, &call->timerList, pTimer);
294          OOTRACEDBGC3("Deleted Session Timer. (%s, %s)\n", 
295                        call->callType, call->callToken);
296          break;
297       }
298    }
299
300  
301    if(!q931Msg->userInfo)
302    {
303       OOTRACEERR3("ERROR:No User-User IE in received ReleaseComplete message "
304                   "(%s, %s)\n", call->callType, call->callToken);
305       return OO_FAILED;
306    }
307
308    releaseComplete = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.releaseComplete;
309    if(!releaseComplete)
310    {
311       OOTRACEWARN3("WARN: ReleaseComplete UUIE not found in received "
312                   "ReleaseComplete message - %s "
313                   "%s\n", call->callType, call->callToken);
314    }
315    else{
316
317       if(releaseComplete->m.reasonPresent)
318       {
319          OOTRACEINFO4("Release complete reason code %d. (%s, %s)\n", 
320                    releaseComplete->reason.t, call->callType, call->callToken);
321          reasonCode = releaseComplete->reason.t;
322       }
323    }
324
325    if(call->callEndReason == OO_REASON_UNKNOWN)
326       call->callEndReason = ooGetCallClearReasonFromCauseAndReasonCode(cause, 
327                                                                    reasonCode);
328    call->q931cause = cause;
329 #if 0
330    if (q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
331        q931Msg->userInfo->h323_uu_pdu.h245Tunneling          &&
332        OO_TESTFLAG (call->flags, OO_M_TUNNELING) )
333    {
334       OOTRACEDBGB3("Handling tunneled messages in ReleaseComplete. (%s, %s)\n",
335                    call->callType, call->callToken);
336       ret = ooHandleTunneledH245Messages
337                     (call, &q931Msg->userInfo->h323_uu_pdu);
338       OOTRACEDBGB3("Finished handling tunneled messages in ReleaseComplete."
339                    " (%s, %s)\n", call->callType, call->callToken);
340    }
341 #endif
342    if(call->h245SessionState != OO_H245SESSION_IDLE && 
343       call->h245SessionState != OO_H245SESSION_CLOSED)
344    {
345       ooCloseH245Connection(call);
346    }
347
348    if(call->callState != OO_CALL_CLEAR_RELEASESENT)
349    {
350       if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
351       {
352          if(gH323ep.gkClient->state == GkClientRegistered){
353             OOTRACEDBGA3("Sending DRQ after received ReleaseComplete."
354                          "(%s, %s)\n", call->callType, call->callToken);
355             ooGkClientSendDisengageRequest(gH323ep.gkClient, call);
356          }
357       }
358    }
359    call->callState = OO_CALL_CLEARED;
360
361    return ret;
362 }
363
364 int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
365 {
366    H225Setup_UUIE *setup=NULL;
367    int i=0, ret=0;
368    H245OpenLogicalChannel* olc;
369    ASN1OCTET msgbuf[MAXMSGLEN];
370    H225TransportAddress_ipAddress_ip *ip = NULL;
371    H225TransportAddress_ip6Address_ip *ip6 = NULL;
372    Q931InformationElement* pDisplayIE=NULL;
373    OOAliases *pAlias=NULL;
374    char remoteIP[2+8*4+7] = "";
375
376    call->callReference = q931Msg->callReference;
377  
378    if(!q931Msg->userInfo)
379    {
380       OOTRACEERR3("ERROR:No User-User IE in received SETUP message (%s, %s)\n",
381                   call->callType, call->callToken);
382       return OO_FAILED;
383    }
384    setup = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.setup;
385    if(!setup)
386    {
387       OOTRACEERR3("Error: Setup UUIE not found in received setup message - %s "
388                   "%s\n", call->callType, call->callToken);
389       return OO_FAILED;
390    }
391    ooHandleH2250ID(call, &setup->protocolIdentifier);
392    memcpy(call->callIdentifier.guid.data, setup->callIdentifier.guid.data, 
393           setup->callIdentifier.guid.numocts);
394    call->callIdentifier.guid.numocts = setup->callIdentifier.guid.numocts;
395    
396    memcpy(call->confIdentifier.data, setup->conferenceID.data,
397           setup->conferenceID.numocts);
398    call->confIdentifier.numocts = setup->conferenceID.numocts;
399
400    /* check for display ie */
401    pDisplayIE = ooQ931GetIE(q931Msg, Q931DisplayIE);
402    if(pDisplayIE)
403    {
404       call->remoteDisplayName = (char *) memAllocZ(call->pctxt, 
405                                  pDisplayIE->length*sizeof(ASN1OCTET)+1);
406       strncpy(call->remoteDisplayName, (char *)pDisplayIE->data, pDisplayIE->length*sizeof(ASN1OCTET));
407    }
408    /*Extract Remote Aliases, if present*/
409    if(setup->m.sourceAddressPresent)
410    {
411       if(setup->sourceAddress.count>0)
412       {
413          ooH323RetrieveAliases(call, &setup->sourceAddress, 
414                                                        &call->remoteAliases);
415          pAlias = call->remoteAliases;
416          while(pAlias)
417          {
418             if(pAlias->type ==  T_H225AliasAddress_dialedDigits)
419             {
420               if(!call->callingPartyNumber)
421               {
422                  call->callingPartyNumber = (char*)memAlloc(call->pctxt,
423                                                     strlen(pAlias->value)*+1);
424                  if(call->callingPartyNumber)
425                  {
426                      strcpy(call->callingPartyNumber, pAlias->value);
427                  }
428               }
429               break;
430            }
431            pAlias = pAlias->next;
432          }
433       }
434    }
435    /* Extract, aliases used for us, if present. Also,
436       Populate calledPartyNumber from dialedDigits, if not yet populated using
437       calledPartyNumber Q931 IE. 
438    */      
439    if(setup->m.destinationAddressPresent)
440    {
441       if(setup->destinationAddress.count>0)
442       {
443          ooH323RetrieveAliases(call, &setup->destinationAddress, 
444                                                        &call->ourAliases);
445          pAlias = call->ourAliases;
446          while(pAlias)
447          {
448             if(pAlias->type == T_H225AliasAddress_dialedDigits)
449             {
450               if(!call->calledPartyNumber)
451               {
452                  call->calledPartyNumber = (char*)memAlloc(call->pctxt,
453                                                     strlen(pAlias->value)*+1);
454                  if(call->calledPartyNumber)
455                  {
456                     strcpy(call->calledPartyNumber, pAlias->value);
457                  }
458               }
459               break;
460             }
461             pAlias = pAlias->next; 
462          }
463       }
464    }
465
466    /* Check for tunneling */
467    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent)
468    {
469       /* Tunneling enabled only when tunneling is set to true and h245
470          address is absent. In the presence of H.245 address in received
471          SETUP message, tunneling is disabled, irrespective of tunneling
472          flag in the setup message*/
473       if(q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
474          !setup->m.h245AddressPresent)
475       {
476          if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
477          {
478             OO_SETFLAG (call->flags, OO_M_TUNNELING);
479             OOTRACEINFO3("Call has tunneling active (%s,%s)\n", call->callType,
480                           call->callToken);
481          }
482          else
483             OOTRACEINFO3("ERROR:Remote endpoint wants to use h245Tunneling, "
484                         "local endpoint has it disabled (%s,%s)\n",
485                         call->callType, call->callToken);
486       }
487       else {
488          if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
489          {
490             OOTRACEINFO3("Tunneling disabled by remote endpoint. (%s, %s)\n",
491                          call->callType, call->callToken);
492          }
493          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
494       }
495    }
496    else {
497       if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
498       {
499          OOTRACEINFO3("Tunneling disabled by remote endpoint. (%s, %s)\n",
500                        call->callType, call->callToken);
501       }
502       OO_CLRFLAG (call->flags, OO_M_TUNNELING);
503    }
504    
505    /* Extract Remote IP address */
506    if(!setup->m.sourceCallSignalAddressPresent)
507    {
508       OOTRACEWARN3("WARNING:Missing source call signal address in received "
509                    "setup (%s, %s)\n", call->callType, call->callToken);
510    }
511    else{
512       if(setup->sourceCallSignalAddress.t == T_H225TransportAddress_ip6Address) {
513         ip6 = &setup->sourceCallSignalAddress.u.ip6Address->ip;
514         inet_ntop(AF_INET6, ip6->data, remoteIP, INET6_ADDRSTRLEN);
515         call->remotePort =  setup->sourceCallSignalAddress.u.ip6Address->port;
516       } else  if(setup->sourceCallSignalAddress.t == T_H225TransportAddress_ipAddress) {
517         ip = &setup->sourceCallSignalAddress.u.ipAddress->ip;
518         sprintf(remoteIP, "%d.%d.%d.%d", ip->data[0], ip->data[1], 
519                                          ip->data[2], ip->data[3]);
520         call->remotePort =  setup->sourceCallSignalAddress.u.ipAddress->port;
521       } else {
522          OOTRACEERR3("ERROR: Source call signalling address type not ip4 nor ip6 "
523                      "(%s, %s)\n", call->callType, call->callToken);
524          return OO_FAILED;
525       }
526    }
527
528    if (strncmp(remoteIP, call->remoteIP, strlen(remoteIP))) {
529      OOTRACEERR5("ERROR: Security denial remote sig IP isn't a socket ip, %s not %s "
530                      "(%s, %s)\n", remoteIP, call->remoteIP, call->callType, 
531                      call->callToken);
532      return OO_FAILED;
533    }
534    
535    /* check for fast start */
536    
537    if(setup->m.fastStartPresent)
538    {
539       if(!OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART))
540       {
541          OOTRACEINFO3("Local endpoint does not support fastStart. Ignoring "
542                      "fastStart. (%s, %s)\n", call->callType, call->callToken);
543          OO_CLRFLAG (call->flags, OO_M_FASTSTART);
544       }
545       else if(setup->fastStart.n == 0)
546       {
547          OOTRACEINFO3("Empty faststart element received. Ignoring fast start. "
548                       "(%s, %s)\n", call->callType, call->callToken);
549          OO_CLRFLAG (call->flags, OO_M_FASTSTART);
550       }
551       else{
552          OO_SETFLAG (call->flags, OO_M_FASTSTART);
553          OOTRACEINFO3("FastStart enabled for call(%s, %s)\n", call->callType,
554                        call->callToken);
555       }
556    }
557
558    if (OO_TESTFLAG (call->flags, OO_M_FASTSTART))
559    {
560       /* For printing the decoded message to log, initialize handler. */
561       initializePrintHandler(&printHandler, "FastStart Elements");
562
563       /* Set print handler */
564       setEventHandler (call->pctxt, &printHandler);
565
566       for(i=0; i<(int)setup->fastStart.n; i++)
567       {
568          olc = NULL;
569          /*         memset(msgbuf, 0, sizeof(msgbuf));*/
570          olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
571                                               sizeof(H245OpenLogicalChannel));
572          if(!olc)
573          {
574             OOTRACEERR3("ERROR:Memory - ooOnReceivedSetup - olc (%s, %s)\n", 
575                         call->callType, call->callToken);
576             /*Mark call for clearing */
577             if(call->callState < OO_CALL_CLEAR)
578             {
579                call->callEndReason = OO_REASON_LOCAL_CLEARED;
580                call->callState = OO_CALL_CLEAR;
581             }
582             return OO_FAILED;
583          }
584          memset(olc, 0, sizeof(H245OpenLogicalChannel));
585          memcpy(msgbuf, setup->fastStart.elem[i].data, 
586                 setup->fastStart.elem[i].numocts);
587
588          setPERBuffer(call->pctxt, msgbuf, 
589                       setup->fastStart.elem[i].numocts, 1);
590          ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
591          if(ret != ASN_OK)
592          {
593             OOTRACEERR3("ERROR:Failed to decode fast start olc element "
594                         "(%s, %s)\n", call->callType, call->callToken);
595             /* Mark call for clearing */
596             if(call->callState < OO_CALL_CLEAR)
597             {
598                call->callEndReason = OO_REASON_INVALIDMESSAGE;
599                call->callState = OO_CALL_CLEAR;
600             }
601             return OO_FAILED;
602          }
603          /* For now, just add decoded fast start elemts to list. This list
604             will be processed at the time of sending CONNECT message. */
605          dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
606       }
607       finishPrint();
608       removeEventHandler(call->pctxt);
609    }
610
611    return OO_OK;
612 }
613
614
615
616 int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
617 {
618    H225CallProceeding_UUIE *callProceeding=NULL;
619    H245OpenLogicalChannel* olc;
620    ASN1OCTET msgbuf[MAXMSGLEN];
621    ooLogicalChannel * pChannel = NULL;
622    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
623    int i=0, ret=0;
624
625    if(!q931Msg->userInfo)
626    {
627       OOTRACEERR3("ERROR:No User-User IE in received CallProceeding message."
628                   " (%s, %s)\n", call->callType, call->callToken);
629       return OO_FAILED;
630    }
631    callProceeding = 
632              q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.callProceeding;
633    if(callProceeding == NULL)
634    {
635       OOTRACEERR3("Error: Received CallProceeding message does not have "
636                   "CallProceeding UUIE (%s, %s)\n", call->callType, 
637                   call->callToken);
638       /* Mark call for clearing */
639       if(call->callState < OO_CALL_CLEAR)
640       {
641          call->callEndReason = OO_REASON_INVALIDMESSAGE;
642          call->callState = OO_CALL_CLEAR;
643       }
644       return OO_FAILED;
645    }
646
647    ooHandleH2250ID(call, &callProceeding->protocolIdentifier);
648    /* Handle fast-start */
649    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART))
650    {
651       if(callProceeding->m.fastStartPresent)
652       {
653          /* For printing the decoded message to log, initialize handler. */
654          initializePrintHandler(&printHandler, "FastStart Elements");
655
656          /* Set print handler */
657          setEventHandler (call->pctxt, &printHandler);
658
659          for(i=0; i<(int)callProceeding->fastStart.n; i++)
660          {
661             olc = NULL;
662
663             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
664                                               sizeof(H245OpenLogicalChannel));
665             if(!olc)
666             {
667                OOTRACEERR3("ERROR:Memory - ooOnReceivedCallProceeding - olc"
668                            "(%s, %s)\n", call->callType, call->callToken);
669                /*Mark call for clearing */
670                if(call->callState < OO_CALL_CLEAR)
671                {
672                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
673                   call->callState = OO_CALL_CLEAR;
674                }
675                return OO_FAILED;
676             }
677             memset(olc, 0, sizeof(H245OpenLogicalChannel));
678             memcpy(msgbuf, callProceeding->fastStart.elem[i].data, 
679                                     callProceeding->fastStart.elem[i].numocts);
680             setPERBuffer(call->pctxt, msgbuf, 
681                          callProceeding->fastStart.elem[i].numocts, 1);
682             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
683             if(ret != ASN_OK)
684             {
685                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
686                            "(%s, %s)\n", call->callType, call->callToken);
687                /* Mark call for clearing */
688                if(call->callState < OO_CALL_CLEAR)
689                {
690                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
691                   call->callState = OO_CALL_CLEAR;
692                }
693                return OO_FAILED;
694             }
695
696             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
697
698             pChannel = ooFindLogicalChannelByOLC(call, olc);
699             if(!pChannel)
700             {
701                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
702                            "(%s, %s)\n",
703                             olc->forwardLogicalChannelNumber, call->callType, 
704                             call->callToken);
705                return OO_FAILED;
706             }
707             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
708             {
709                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
710                             "Number from %d to %d (%s, %s)\n", 
711                             pChannel->channelNo, 
712                             olc->forwardLogicalChannelNumber, call->callType, 
713                             call->callToken);
714                pChannel->channelNo = olc->forwardLogicalChannelNumber;
715             }
716             if(!strcmp(pChannel->dir, "transmit"))
717             {
718                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
719                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
720                {
721                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
722                               "channel %d (%s, %s)\n", 
723                               olc->forwardLogicalChannelNumber, call->callType,
724                               call->callToken);
725                   continue;
726                }
727             
728                /* Extract the remote media endpoint address */
729                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
730                if(!h2250lcp)
731                {
732                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
733                               "forward Logical Channel Parameters found. "
734                               "(%s, %s)\n", call->callType, call->callToken);
735                   return OO_FAILED;
736                }
737                if(!h2250lcp->m.mediaChannelPresent)
738                {
739                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
740                               "reverse media channel information found."
741                               "(%s, %s)\n", call->callType, call->callToken);
742                   return OO_FAILED;
743                }
744                ret = ooGetIpPortFromH245TransportAddress(call, 
745                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
746                                    &pChannel->remoteMediaPort);
747                
748                if(ret != OO_OK)
749                {
750                 if(call->callState < OO_CALL_CLEAR)
751                 {
752                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
753                   call->callState = OO_CALL_CLEAR;
754                 }
755                   OOTRACEERR3("ERROR:Unsupported media channel address type "
756                               "(%s, %s)\n", call->callType, call->callToken);
757                   return OO_FAILED;
758                }
759        
760                if(!pChannel->chanCap->startTransmitChannel)
761                {
762                   OOTRACEERR3("ERROR:No callback registered to start transmit "
763                               "channel (%s, %s)\n",call->callType, 
764                               call->callToken);
765                   return OO_FAILED;
766                }
767                pChannel->chanCap->startTransmitChannel(call, pChannel);
768             }
769             /* Mark the current channel as established and close all other 
770                logical channels with same session id and in same direction.
771             */
772             ooOnLogicalChannelEstablished(call, pChannel);
773          }
774          finishPrint();
775          removeEventHandler(call->pctxt);
776          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
777       }
778       
779    }
780
781    /* Retrieve tunneling info/H.245 control channel address from the connect msg */
782    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && 
783       !q931Msg->userInfo->h323_uu_pdu.h245Tunneling) {
784         if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
785                 OO_CLRFLAG (call->flags, OO_M_TUNNELING);
786                 OOTRACEINFO3("Tunneling is disabled for call due to remote reject tunneling"
787                               " (%s, %s)\n", call->callType, call->callToken);
788         }
789    }
790    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
791       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
792       OO_TESTFLAG (call->flags, OO_M_TUNNELING) &&
793       callProceeding->m.h245AddressPresent) {
794       OOTRACEINFO3("Tunneling and h245address provided."
795                    "Using Tunneling for H.245 messages (%s, %s)\n", 
796                    call->callType, call->callToken);
797    }
798    else if(callProceeding->m.h245AddressPresent)
799    {
800       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
801       {
802          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
803          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
804                       "provided in callProceeding message (%s, %s)\n", 
805                       call->callType, call->callToken);
806       }
807       ret = ooH323GetIpPortFromH225TransportAddress(call, 
808                                   &callProceeding->h245Address, call->remoteIP,
809                                   &call->remoteH245Port);
810       if(ret != OO_OK)
811       {
812          OOTRACEERR3("Error: Unknown H245 address type in received "
813                      "CallProceeding message (%s, %s)", call->callType, 
814                      call->callToken);
815          /* Mark call for clearing */
816          if(call->callState < OO_CALL_CLEAR)
817          {
818             call->callEndReason = OO_REASON_INVALIDMESSAGE;
819             call->callState = OO_CALL_CLEAR;
820          }
821          return OO_FAILED;
822       }
823       if(call->remoteH245Port != 0 && !call->pH245Channel) {
824       /* Create an H.245 connection. 
825       */
826        if(ooCreateH245Connection(call)== OO_FAILED)
827        {
828          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
829                      call->callType, call->callToken);
830
831          if(call->callState < OO_CALL_CLEAR)
832          {
833             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
834             call->callState = OO_CALL_CLEAR;
835          }
836          return OO_FAILED;
837        }
838       }
839    }
840
841    return OO_OK;
842 }
843
844
845 int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
846 {
847    H225Alerting_UUIE *alerting=NULL;
848    H245OpenLogicalChannel* olc;
849    ASN1OCTET msgbuf[MAXMSGLEN];
850    ooLogicalChannel * pChannel = NULL;
851    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
852    int i=0, ret=0;
853
854    ooHandleDisplayIE(call, q931Msg);
855
856    if(!q931Msg->userInfo)
857    {
858       OOTRACEERR3("ERROR:No User-User IE in received Alerting message."
859                   " (%s, %s)\n", call->callType, call->callToken);
860       return OO_FAILED;
861    }
862    alerting = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.alerting;
863    if(alerting == NULL)
864    {
865       OOTRACEERR3("Error: Received Alerting message does not have "
866                   "alerting UUIE (%s, %s)\n", call->callType, 
867                   call->callToken);
868       /* Mark call for clearing */
869       if(call->callState < OO_CALL_CLEAR)
870       {
871          call->callEndReason = OO_REASON_INVALIDMESSAGE;
872          call->callState = OO_CALL_CLEAR;
873       }
874       return OO_FAILED;
875    }
876    ooHandleH2250ID(call, &alerting->protocolIdentifier);
877    /*Handle fast-start */
878    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
879       !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
880    {
881       if(alerting->m.fastStartPresent)
882       {
883          /* For printing the decoded message to log, initialize handler. */
884          initializePrintHandler(&printHandler, "FastStart Elements");
885
886          /* Set print handler */
887          setEventHandler (call->pctxt, &printHandler);
888
889          for(i=0; i<(int)alerting->fastStart.n; i++)
890          {
891             olc = NULL;
892
893             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
894                                               sizeof(H245OpenLogicalChannel));
895             if(!olc)
896             {
897                OOTRACEERR3("ERROR:Memory - ooOnReceivedAlerting - olc"
898                            "(%s, %s)\n", call->callType, call->callToken);
899                /*Mark call for clearing */
900                if(call->callState < OO_CALL_CLEAR)
901                {
902                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
903                   call->callState = OO_CALL_CLEAR;
904                }
905                return OO_FAILED;
906             }
907             memset(olc, 0, sizeof(H245OpenLogicalChannel));
908             memcpy(msgbuf, alerting->fastStart.elem[i].data, 
909                                     alerting->fastStart.elem[i].numocts);
910             setPERBuffer(call->pctxt, msgbuf, 
911                          alerting->fastStart.elem[i].numocts, 1);
912             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
913             if(ret != ASN_OK)
914             {
915                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
916                            "(%s, %s)\n", call->callType, call->callToken);
917                /* Mark call for clearing */
918                if(call->callState < OO_CALL_CLEAR)
919                {
920                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
921                   call->callState = OO_CALL_CLEAR;
922                }
923                return OO_FAILED;
924             }
925
926             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
927
928             pChannel = ooFindLogicalChannelByOLC(call, olc);
929             if(!pChannel)
930             {
931                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
932                            "(%s, %s)\n",
933                             olc->forwardLogicalChannelNumber, call->callType, 
934                             call->callToken);
935                return OO_FAILED;
936             }
937             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
938             {
939                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
940                             "Number from %d to %d (%s, %s)\n", 
941                             pChannel->channelNo, 
942                             olc->forwardLogicalChannelNumber, call->callType, 
943                             call->callToken);
944                pChannel->channelNo = olc->forwardLogicalChannelNumber;
945             }
946             if(!strcmp(pChannel->dir, "transmit"))
947             {
948                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
949                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
950                {
951                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
952                               "channel %d (%s, %s)\n", 
953                               olc->forwardLogicalChannelNumber, call->callType,
954                               call->callToken);
955                   continue;
956                }
957             
958                /* Extract the remote media endpoint address */
959                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
960                if(!h2250lcp)
961                {
962                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
963                               "forward Logical Channel Parameters found. "
964                               "(%s, %s)\n", call->callType, call->callToken);
965                   return OO_FAILED;
966                }
967                if(!h2250lcp->m.mediaChannelPresent)
968                {
969                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
970                               "reverse media channel information found."
971                               "(%s, %s)\n", call->callType, call->callToken);
972                   return OO_FAILED;
973                }
974                ret = ooGetIpPortFromH245TransportAddress(call, 
975                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
976                                    &pChannel->remoteMediaPort);
977                
978                if(ret != OO_OK)
979                {
980                 if(call->callState < OO_CALL_CLEAR)
981                 {
982                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
983                   call->callState = OO_CALL_CLEAR;
984                 }
985                   OOTRACEERR3("ERROR:Unsupported media channel address type "
986                               "(%s, %s)\n", call->callType, call->callToken);
987                   return OO_FAILED;
988                }
989        
990                if(!pChannel->chanCap->startTransmitChannel)
991                {
992                   OOTRACEERR3("ERROR:No callback registered to start transmit "
993                               "channel (%s, %s)\n",call->callType, 
994                               call->callToken);
995                   return OO_FAILED;
996                }
997                pChannel->chanCap->startTransmitChannel(call, pChannel);
998                /* Mark the current channel as established and close all other 
999                   logical channels with same session id and in same direction.
1000                */
1001                ooOnLogicalChannelEstablished(call, pChannel);
1002             }
1003          }
1004          finishPrint();
1005          removeEventHandler(call->pctxt);
1006          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
1007       } 
1008
1009    }
1010
1011    /* Retrieve tunneling info/H.245 control channel address from the connect msg */
1012    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && 
1013       !q931Msg->userInfo->h323_uu_pdu.h245Tunneling) {
1014         if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1015                 OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1016                 OOTRACEINFO3("Tunneling is disabled for call due to remote reject tunneling"
1017                               " (%s, %s)\n", call->callType, call->callToken);
1018         }
1019    }
1020    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
1021       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
1022          OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1023       if (alerting->m.h245AddressPresent) 
1024         OOTRACEINFO3("Tunneling and h245address provided."
1025                      "Giving preference to Tunneling (%s, %s)\n", 
1026                         call->callType, call->callToken);
1027         if (call->h225version >= 4) {
1028                 ret =ooSendTCSandMSD(call);
1029         }
1030         if (ret != OO_OK)
1031                 return ret;
1032
1033    } else if(alerting->m.h245AddressPresent) {
1034       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1035       {
1036          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1037          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
1038                       "provided in Alerting message (%s, %s)\n", 
1039                       call->callType, call->callToken);
1040       }
1041       ret = ooH323GetIpPortFromH225TransportAddress(call, 
1042                                   &alerting->h245Address, call->remoteIP,
1043                                   &call->remoteH245Port);
1044       if(ret != OO_OK)
1045       {
1046          OOTRACEERR3("Error: Unknown H245 address type in received "
1047                      "Alerting message (%s, %s)", call->callType, 
1048                      call->callToken);
1049          /* Mark call for clearing */
1050          if(call->callState < OO_CALL_CLEAR)
1051          {
1052             call->callEndReason = OO_REASON_INVALIDMESSAGE;
1053             call->callState = OO_CALL_CLEAR;
1054          }
1055          return OO_FAILED;
1056       }
1057       if(call->remoteH245Port != 0 && !call->pH245Channel) {
1058       /* Create an H.245 connection. 
1059       */
1060        if(ooCreateH245Connection(call)== OO_FAILED)
1061        {
1062          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
1063                      call->callType, call->callToken);
1064
1065          if(call->callState < OO_CALL_CLEAR)
1066          {
1067             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1068             call->callState = OO_CALL_CLEAR;
1069          }
1070          return OO_FAILED;
1071        } else {
1072         if (call->h225version >= 4) {
1073                 ret =ooSendTCSandMSD(call);
1074         }
1075        }
1076       }
1077    }
1078
1079    return OO_OK;
1080 }
1081
1082 int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
1083 {
1084    H225Progress_UUIE *progress=NULL;
1085    H245OpenLogicalChannel* olc;
1086    ASN1OCTET msgbuf[MAXMSGLEN];
1087    ooLogicalChannel * pChannel = NULL;
1088    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
1089    int i=0, ret=0;
1090
1091    ooHandleDisplayIE(call, q931Msg);
1092
1093    if(!q931Msg->userInfo)
1094    {
1095       OOTRACEERR3("ERROR:No User-User IE in received Progress message."
1096                   " (%s, %s)\n", call->callType, call->callToken);
1097       return OO_FAILED;
1098    }
1099    progress = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.progress;
1100    if(progress == NULL)
1101    {
1102       OOTRACEERR3("Error: Received Progress message does not have "
1103                   "progress UUIE (%s, %s)\n", call->callType, 
1104                   call->callToken);
1105       /* Mark call for clearing */
1106       if(call->callState < OO_CALL_CLEAR)
1107       {
1108          call->callEndReason = OO_REASON_INVALIDMESSAGE;
1109          call->callState = OO_CALL_CLEAR;
1110       }
1111       return OO_FAILED;
1112    }
1113    ooHandleH2250ID(call, &progress->protocolIdentifier);
1114    /*Handle fast-start */
1115    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
1116       !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
1117    {
1118       if(progress->m.fastStartPresent)
1119       {
1120          /* For printing the decoded message to log, initialize handler. */
1121          initializePrintHandler(&printHandler, "FastStart Elements");
1122
1123          /* Set print handler */
1124          setEventHandler (call->pctxt, &printHandler);
1125
1126          for(i=0; i<(int)progress->fastStart.n; i++)
1127          {
1128             olc = NULL;
1129
1130             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
1131                                               sizeof(H245OpenLogicalChannel));
1132             if(!olc)
1133             {
1134                OOTRACEERR3("ERROR:Memory - ooOnReceivedProgress - olc"
1135                            "(%s, %s)\n", call->callType, call->callToken);
1136                /*Mark call for clearing */
1137                if(call->callState < OO_CALL_CLEAR)
1138                {
1139                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
1140                   call->callState = OO_CALL_CLEAR;
1141                }
1142                return OO_FAILED;
1143             }
1144             memset(olc, 0, sizeof(H245OpenLogicalChannel));
1145             memcpy(msgbuf, progress->fastStart.elem[i].data, 
1146                                     progress->fastStart.elem[i].numocts);
1147             setPERBuffer(call->pctxt, msgbuf, 
1148                          progress->fastStart.elem[i].numocts, 1);
1149             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
1150             if(ret != ASN_OK)
1151             {
1152                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
1153                            "(%s, %s)\n", call->callType, call->callToken);
1154                /* Mark call for clearing */
1155                if(call->callState < OO_CALL_CLEAR)
1156                {
1157                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
1158                   call->callState = OO_CALL_CLEAR;
1159                }
1160                return OO_FAILED;
1161             }
1162
1163             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
1164
1165             pChannel = ooFindLogicalChannelByOLC(call, olc);
1166             if(!pChannel)
1167             {
1168                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
1169                            "(%s, %s)\n",
1170                             olc->forwardLogicalChannelNumber, call->callType, 
1171                             call->callToken);
1172                return OO_FAILED;
1173             }
1174             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
1175             {
1176                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
1177                             "Number from %d to %d (%s, %s)\n", 
1178                             pChannel->channelNo, 
1179                             olc->forwardLogicalChannelNumber, call->callType, 
1180                             call->callToken);
1181                pChannel->channelNo = olc->forwardLogicalChannelNumber;
1182             }
1183             if(!strcmp(pChannel->dir, "transmit"))
1184             {
1185                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
1186                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
1187                {
1188                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
1189                               "channel %d (%s, %s)\n", 
1190                               olc->forwardLogicalChannelNumber, call->callType,
1191                               call->callToken);
1192                   continue;
1193                }
1194             
1195                /* Extract the remote media endpoint address */
1196                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
1197                if(!h2250lcp)
1198                {
1199                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1200                               "forward Logical Channel Parameters found. "
1201                               "(%s, %s)\n", call->callType, call->callToken);
1202                   return OO_FAILED;
1203                }
1204                if(!h2250lcp->m.mediaChannelPresent)
1205                {
1206                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1207                               "reverse media channel information found."
1208                               "(%s, %s)\n", call->callType, call->callToken);
1209                   return OO_FAILED;
1210                }
1211                ret = ooGetIpPortFromH245TransportAddress(call, 
1212                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
1213                                    &pChannel->remoteMediaPort);
1214                
1215                if(ret != OO_OK)
1216                {
1217                 if(call->callState < OO_CALL_CLEAR)
1218                 {
1219                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
1220                   call->callState = OO_CALL_CLEAR;
1221                 }
1222                   OOTRACEERR3("ERROR:Unsupported media channel address type "
1223                               "(%s, %s)\n", call->callType, call->callToken);
1224                   return OO_FAILED;
1225                }
1226        
1227                if(!pChannel->chanCap->startTransmitChannel)
1228                {
1229                   OOTRACEERR3("ERROR:No callback registered to start transmit "
1230                               "channel (%s, %s)\n",call->callType, 
1231                               call->callToken);
1232                   return OO_FAILED;
1233                }
1234                pChannel->chanCap->startTransmitChannel(call, pChannel);
1235             }
1236             /* Mark the current channel as established and close all other 
1237                logical channels with same session id and in same direction.
1238             */
1239             ooOnLogicalChannelEstablished(call, pChannel);
1240          }
1241          finishPrint();
1242          removeEventHandler(call->pctxt);
1243          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
1244       }
1245       
1246    }
1247
1248    /* Retrieve the H.245 control channel address from the connect msg */
1249    /* Retrieve tunneling info/H.245 control channel address from the connect msg */
1250    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && 
1251       !q931Msg->userInfo->h323_uu_pdu.h245Tunneling) {
1252         if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1253                 OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1254                 OOTRACEINFO3("Tunneling is disabled for call due to remote reject tunneling"
1255                               " (%s, %s)\n", call->callType, call->callToken);
1256         }
1257    }
1258    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
1259       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
1260       OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1261       if (progress->m.h245AddressPresent) 
1262         OOTRACEINFO3("Tunneling and h245address provided."
1263                      "Giving preference to Tunneling (%s, %s)\n", 
1264                      call->callType, call->callToken);
1265         if (call->h225version >= 4) {
1266                 ret =ooSendTCSandMSD(call);
1267         }
1268         if (ret != OO_OK)
1269                 return ret;
1270    } else if(progress->m.h245AddressPresent) {
1271       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1272       {
1273          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1274          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
1275                       "provided in Progress message (%s, %s)\n", 
1276                       call->callType, call->callToken);
1277       }
1278       ret = ooH323GetIpPortFromH225TransportAddress(call, 
1279                                   &progress->h245Address, call->remoteIP,
1280                                   &call->remoteH245Port);
1281       if(ret != OO_OK)
1282       {
1283          OOTRACEERR3("Error: Unknown H245 address type in received "
1284                      "Progress message (%s, %s)", call->callType, 
1285                      call->callToken);
1286          /* Mark call for clearing */
1287          if(call->callState < OO_CALL_CLEAR)
1288          {
1289             call->callEndReason = OO_REASON_INVALIDMESSAGE;
1290             call->callState = OO_CALL_CLEAR;
1291          }
1292          return OO_FAILED;
1293       }
1294       if(call->remoteH245Port != 0 && !call->pH245Channel) {
1295        /* Create an H.245 connection. 
1296       */
1297        if(ooCreateH245Connection(call)== OO_FAILED)
1298        {
1299          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
1300                      call->callType, call->callToken);
1301
1302          if(call->callState < OO_CALL_CLEAR)
1303          {
1304             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1305             call->callState = OO_CALL_CLEAR;
1306          }
1307          return OO_FAILED;
1308        } else {
1309         if (call->h225version >= 4) {
1310                 ret =ooSendTCSandMSD(call);
1311         }
1312        }
1313       }
1314    }
1315
1316    return OO_OK;
1317 }
1318    
1319
1320 int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
1321 {
1322    int ret, i;
1323    H225Connect_UUIE *connect;
1324    H245OpenLogicalChannel* olc;
1325    ASN1OCTET msgbuf[MAXMSGLEN];
1326    ooLogicalChannel * pChannel = NULL;
1327    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
1328
1329    ooHandleDisplayIE(call, q931Msg);
1330
1331    if(!q931Msg->userInfo)
1332    {
1333       OOTRACEERR3("Error: UUIE not found in received H.225 Connect message"
1334                   " (%s, %s)\n", call->callType, call->callToken);
1335       /* Mark call for clearing */
1336       if(call->callState < OO_CALL_CLEAR)
1337       {
1338          call->callEndReason = OO_REASON_INVALIDMESSAGE;
1339          call->callState = OO_CALL_CLEAR;
1340       }
1341       return OO_FAILED;
1342    }
1343    /* Retrieve the connect message from the user-user IE & Q.931 header */
1344    connect = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.connect;
1345    if(connect == NULL)
1346    {
1347       OOTRACEERR3("Error: Received Connect message does not have Connect UUIE"
1348                   " (%s, %s)\n", call->callType, call->callToken);
1349       /* Mark call for clearing */
1350       if(call->callState < OO_CALL_CLEAR)
1351       {
1352          call->callEndReason = OO_REASON_INVALIDMESSAGE;
1353          call->callState = OO_CALL_CLEAR;
1354       }
1355       return OO_FAILED;
1356    }
1357    ooHandleH2250ID(call, &connect->protocolIdentifier);
1358    /*Handle fast-start */
1359    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) && 
1360       !OO_TESTFLAG (call->flags, OO_M_FASTSTARTANSWERED))
1361    {
1362       if(!connect->m.fastStartPresent)
1363       {
1364          OOTRACEINFO3("Remote endpoint has rejected fastStart. (%s, %s)\n",
1365                       call->callType, call->callToken);
1366          /* Clear all channels we might have created */
1367          ooClearAllLogicalChannels(call);
1368          OO_CLRFLAG (call->flags, OO_M_FASTSTART);
1369       }
1370    }
1371
1372    if (connect->m.fastStartPresent && 
1373        !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
1374    {
1375       /* For printing the decoded message to log, initialize handler. */
1376       initializePrintHandler(&printHandler, "FastStart Elements");
1377
1378       /* Set print handler */
1379       setEventHandler (call->pctxt, &printHandler);
1380
1381       for(i=0; i<(int)connect->fastStart.n; i++)
1382       {
1383          olc = NULL;
1384          /* memset(msgbuf, 0, sizeof(msgbuf));*/
1385          olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
1386                                               sizeof(H245OpenLogicalChannel));
1387          if(!olc)
1388          {
1389             OOTRACEERR3("ERROR:Memory - ooOnReceivedSignalConnect - olc"
1390                         "(%s, %s)\n", call->callType, call->callToken);
1391             /*Mark call for clearing */
1392             if(call->callState < OO_CALL_CLEAR)
1393             {
1394                call->callEndReason = OO_REASON_LOCAL_CLEARED;
1395                call->callState = OO_CALL_CLEAR;
1396             }
1397             finishPrint();
1398             removeEventHandler(call->pctxt);
1399             return OO_FAILED;
1400          }
1401          memset(olc, 0, sizeof(H245OpenLogicalChannel));
1402          memcpy(msgbuf, connect->fastStart.elem[i].data, 
1403                                            connect->fastStart.elem[i].numocts);
1404          setPERBuffer(call->pctxt, msgbuf, 
1405                       connect->fastStart.elem[i].numocts, 1);
1406          ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
1407          if(ret != ASN_OK)
1408          {
1409             OOTRACEERR3("ERROR:Failed to decode fast start olc element "
1410                         "(%s, %s)\n", call->callType, call->callToken);
1411             /* Mark call for clearing */
1412             if(call->callState < OO_CALL_CLEAR)
1413             {
1414                call->callEndReason = OO_REASON_INVALIDMESSAGE;
1415                call->callState = OO_CALL_CLEAR;
1416             }
1417             finishPrint();
1418             removeEventHandler(call->pctxt);
1419             return OO_FAILED;
1420          }
1421
1422          dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
1423
1424          pChannel = ooFindLogicalChannelByOLC(call, olc);
1425          if(!pChannel)
1426          {
1427             OOTRACEERR4("ERROR: Logical Channel %d not found, fasts start "
1428                         "answered. (%s, %s)\n",
1429                          olc->forwardLogicalChannelNumber, call->callType, 
1430                          call->callToken);
1431             finishPrint();
1432             removeEventHandler(call->pctxt);
1433             return OO_FAILED;
1434          }
1435          if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
1436          {
1437             OOTRACEINFO5("Remote endpoint changed forwardLogicalChannelNumber"
1438                          "from %d to %d (%s, %s)\n", pChannel->channelNo,
1439                           olc->forwardLogicalChannelNumber, call->callType, 
1440                           call->callToken);
1441             pChannel->channelNo = olc->forwardLogicalChannelNumber;
1442          }
1443          if(!strcmp(pChannel->dir, "transmit"))
1444          {
1445             if(olc->forwardLogicalChannelParameters.multiplexParameters.t != 
1446                T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
1447             {
1448                OOTRACEERR4("ERROR:Unknown multiplex parameter type for channel"
1449                            " %d (%s, %s)\n", olc->forwardLogicalChannelNumber, 
1450                            call->callType, call->callToken);
1451                continue;
1452             }
1453             
1454             /* Extract the remote media endpoint address */
1455             h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
1456             if(!h2250lcp)
1457             {
1458                OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1459                            "forward Logical Channel Parameters found. (%s, %s)"
1460                            "\n", call->callType, call->callToken);
1461                finishPrint();
1462                removeEventHandler(call->pctxt);
1463                return OO_FAILED;
1464             }
1465             if(!h2250lcp->m.mediaChannelPresent)
1466             {
1467                OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1468                            "reverse media channel information found. (%s, %s)"
1469                            "\n", call->callType, call->callToken);
1470                finishPrint();
1471                removeEventHandler(call->pctxt);
1472                return OO_FAILED;
1473             }
1474
1475             ret = ooGetIpPortFromH245TransportAddress(call, 
1476                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
1477                                    &pChannel->remoteMediaPort);
1478             if(ret != OO_OK)
1479             {
1480                 if(call->callState < OO_CALL_CLEAR)
1481                 {
1482                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
1483                   call->callState = OO_CALL_CLEAR;
1484                 }
1485                OOTRACEERR3("ERROR:Unsupported media channel address type "
1486                            "(%s, %s)\n", call->callType, call->callToken);
1487                finishPrint();
1488                removeEventHandler(call->pctxt);
1489                return OO_FAILED;
1490             }
1491             if(!pChannel->chanCap->startTransmitChannel)
1492             {
1493                OOTRACEERR3("ERROR:No callback registered to start transmit "
1494                          "channel (%s, %s)\n",call->callType, call->callToken);
1495                finishPrint();
1496                removeEventHandler(call->pctxt);
1497                return OO_FAILED;
1498             }
1499             pChannel->chanCap->startTransmitChannel(call, pChannel);
1500          }
1501          /* Mark the current channel as established and close all other 
1502             logical channels with same session id and in same direction.
1503          */
1504          ooOnLogicalChannelEstablished(call, pChannel);
1505       }
1506       finishPrint();
1507       removeEventHandler(call->pctxt);
1508       OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
1509    }
1510
1511    /* Retrieve tunneling info/H.245 control channel address from the connect msg */
1512    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && 
1513       !q931Msg->userInfo->h323_uu_pdu.h245Tunneling) {
1514         if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1515                 OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1516                 OOTRACEINFO3("Tunneling is disabled for call due to remote reject tunneling"
1517                               " (%s, %s)\n", call->callType, call->callToken);
1518         }
1519    }
1520    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
1521       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
1522       OO_TESTFLAG (call->flags, OO_M_TUNNELING) &&
1523       connect->m.h245AddressPresent) {
1524       OOTRACEINFO3("Tunneling and h245address provided."
1525                    "Giving preference to Tunneling (%s, %s)\n", 
1526                    call->callType, call->callToken);
1527    }
1528    else if(connect->m.h245AddressPresent)
1529    {
1530       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1531       {
1532          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1533          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
1534                       "provided in connect message (%s, %s)\n", 
1535                       call->callType, call->callToken);
1536       }
1537       ret = ooH323GetIpPortFromH225TransportAddress(call, 
1538                  &connect->h245Address, call->remoteIP, &call->remoteH245Port);
1539       if(ret != OO_OK)
1540       {
1541          OOTRACEERR3("Error: Unknown H245 address type in received Connect "
1542                      "message (%s, %s)", call->callType, call->callToken);
1543          /* Mark call for clearing */
1544          if(call->callState < OO_CALL_CLEAR)
1545          {
1546             call->callEndReason = OO_REASON_INVALIDMESSAGE;
1547             call->callState = OO_CALL_CLEAR;
1548          }
1549          return OO_FAILED;
1550       }
1551    }
1552
1553    if(call->remoteH245Port != 0 && !call->pH245Channel)
1554    {
1555        /* Create an H.245 connection. 
1556       */
1557       if(ooCreateH245Connection(call)== OO_FAILED)
1558       {
1559          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
1560                      call->callType, call->callToken);
1561
1562          if(call->callState < OO_CALL_CLEAR)
1563          {
1564             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1565             call->callState = OO_CALL_CLEAR;
1566          }
1567          return OO_FAILED;
1568       }
1569    }
1570
1571    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent)
1572    {
1573       if (!q931Msg->userInfo->h323_uu_pdu.h245Tunneling)
1574       {
1575          if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1576          {
1577             OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1578             OOTRACEINFO3("Tunneling is disabled by remote endpoint.(%s, %s)\n",
1579                           call->callType, call->callToken);
1580          }
1581       }
1582    }
1583    if (OO_TESTFLAG(call->flags, OO_M_TUNNELING))
1584    {
1585       OOTRACEDBGB3("Handling tunneled messages in CONNECT. (%s, %s)\n",
1586                     call->callType, call->callToken);
1587       ret = ooHandleTunneledH245Messages
1588          (call, &q931Msg->userInfo->h323_uu_pdu);
1589       OOTRACEDBGB3("Finished tunneled messages in Connect. (%s, %s)\n",
1590                     call->callType, call->callToken);
1591
1592    }
1593    /*
1594         Send TCS as call established and no capability exchange has yet 
1595         started. This will be true only when separate h245 connection is not
1596         established and tunneling is being used.
1597    */
1598    if(call->localTermCapState == OO_LocalTermCapExchange_Idle)
1599    {
1600         /*Start terminal capability exchange and master slave determination */
1601         ret = ooSendTermCapMsg(call);
1602         if(ret != OO_OK)
1603         {
1604            OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
1605                         call->callType, call->callToken);
1606            return ret;
1607         }
1608    }
1609
1610    call->callState = OO_CALL_CONNECTED;
1611    if (call->rtdrCount > 0 && call->rtdrInterval > 0) {
1612         return ooSendRoundTripDelayRequest(call);
1613    }
1614    return OO_OK;  
1615 }
1616
1617 int ooHandleH2250Message(OOH323CallData *call, Q931Message *q931Msg)
1618 {
1619    int ret=OO_OK;
1620    ASN1UINT i;
1621    DListNode *pNode = NULL;
1622    OOTimer *pTimer=NULL;
1623    int type = q931Msg->messageType;
1624    struct timeval tv;
1625    struct timespec ts;
1626
1627 /* checking of message validity for first/next messages of calls */
1628
1629    if (!strcmp(call->callType, "incoming")) {
1630         if ((call->callState != OO_CALL_CREATED && type == Q931SetupMsg) ||
1631             (call->callState == OO_CALL_CREATED && type != Q931SetupMsg)) {
1632                 ooFreeQ931Message(call->msgctxt, q931Msg);
1633                 return OO_FAILED;
1634         }
1635    }
1636
1637    switch(type)
1638    {
1639       case Q931SetupMsg: /* SETUP message is received */
1640          OOTRACEINFO3("Received SETUP message (%s, %s)\n", call->callType,
1641                        call->callToken);
1642          ret = ooOnReceivedSetup(call, q931Msg);
1643          if (ret != OO_OK) {
1644            call->callState = OO_CALL_CLEAR;
1645          } else {
1646            
1647          /* H225 message callback */
1648             if(gH323ep.h225Callbacks.onReceivedSetup)
1649                ret = gH323ep.h225Callbacks.onReceivedSetup(call, q931Msg);
1650          }
1651          /* Free up the mem used by the received message, as it's processing 
1652             is done. 
1653          */
1654          if (ret == OO_OK) {
1655
1656          ooFreeQ931Message(call->msgctxt, q931Msg);
1657          
1658          /* DISABLEGK is used to selectively disable gatekeeper use. For 
1659             incoming calls DISABLEGK can be set in onReceivedSetup callback by 
1660             application. Very useful in pbx applications where gk is used only 
1661             when call is to or from outside pbx domian
1662          */
1663          if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
1664          {
1665             if(gH323ep.gkClient->state == GkClientRegistered)
1666             {
1667                call->callState = OO_CALL_WAITING_ADMISSION;
1668                ret = ooGkClientSendAdmissionRequest(gH323ep.gkClient, call, 
1669                                                     FALSE);
1670                 tv = ast_tvnow();
1671                 ts.tv_sec = tv.tv_sec + 24;
1672                 ts.tv_nsec = tv.tv_usec * 1000;
1673                 ast_mutex_lock(&call->GkLock);
1674                 if (call->callState == OO_CALL_WAITING_ADMISSION)
1675                    ast_cond_timedwait(&call->gkWait, &call->GkLock, &ts);
1676                 if (call->callState == OO_CALL_WAITING_ADMISSION)
1677                         call->callState = OO_CALL_CLEAR;
1678                 ast_mutex_unlock(&call->GkLock);
1679
1680             }
1681             else {
1682                OOTRACEERR1("Error:Ignoring incoming call as not yet"
1683                            "registered with Gk\n");
1684                call->callState = OO_CALL_CLEAR;
1685                call->callEndReason = OO_REASON_GK_UNREACHABLE;
1686             }
1687          }
1688          if (call->callState < OO_CALL_CLEAR) {
1689                 ooSendCallProceeding(call);/* Send call proceeding message*/
1690                 ret = ooH323CallAdmitted (call);
1691           }
1692
1693          call->callState = OO_CALL_CONNECTING;
1694
1695          } /* end ret == OO_OK */
1696          break;
1697
1698
1699       case Q931CallProceedingMsg: /* CALL PROCEEDING message is received */
1700          OOTRACEINFO3("H.225 Call Proceeding message received (%s, %s)\n",
1701                       call->callType, call->callToken);
1702          ooOnReceivedCallProceeding(call, q931Msg);
1703
1704          ooFreeQ931Message(call->msgctxt, q931Msg);
1705          break;
1706
1707
1708       case Q931AlertingMsg:/* ALERTING message received */
1709          OOTRACEINFO3("H.225 Alerting message received (%s, %s)\n", 
1710                       call->callType, call->callToken);
1711
1712          call->alertingTime = (H235TimeStamp) time(NULL);
1713          ooOnReceivedAlerting(call, q931Msg);
1714
1715          if(gH323ep.h323Callbacks.onAlerting && call->callState<OO_CALL_CLEAR)
1716             gH323ep.h323Callbacks.onAlerting(call);
1717          ooFreeQ931Message(call->msgctxt, q931Msg);
1718          break;
1719
1720
1721       case Q931ProgressMsg:/* PROGRESS message received */
1722          OOTRACEINFO3("H.225 Progress message received (%s, %s)\n", 
1723                       call->callType, call->callToken);
1724
1725          ooOnReceivedProgress(call, q931Msg);
1726
1727          if(gH323ep.h323Callbacks.onProgress && call->callState<OO_CALL_CLEAR)
1728             gH323ep.h323Callbacks.onProgress(call);
1729          ooFreeQ931Message(call->msgctxt, q931Msg);
1730          break;
1731
1732
1733       case Q931ConnectMsg:/* CONNECT message received */
1734          OOTRACEINFO3("H.225 Connect message received (%s, %s)\n",
1735                       call->callType, call->callToken);
1736
1737          call->connectTime = (H235TimeStamp) time(NULL);
1738
1739          /* Disable call establishment timer */
1740          for(i = 0; i<call->timerList.count; i++)
1741          {
1742             pNode = dListFindByIndex(&call->timerList, i);
1743             pTimer = (OOTimer*)pNode->data;
1744             if(((ooTimerCallback*)pTimer->cbData)->timerType & 
1745                                                          OO_CALLESTB_TIMER)
1746             {
1747                memFreePtr(call->pctxt, pTimer->cbData);
1748                ooTimerDelete(call->pctxt, &call->timerList, pTimer);
1749                OOTRACEDBGC3("Deleted CallESTB timer. (%s, %s)\n", 
1750                                               call->callType, call->callToken);
1751                break;
1752             }
1753          }
1754          ret = ooOnReceivedSignalConnect(call, q931Msg);
1755          if(ret != OO_OK)
1756             OOTRACEERR3("Error:Invalid Connect message received. (%s, %s)\n",
1757                         call->callType, call->callToken);
1758          else{
1759              /* H225 message callback */
1760             if(gH323ep.h225Callbacks.onReceivedConnect)
1761                gH323ep.h225Callbacks.onReceivedConnect(call, q931Msg);
1762
1763             if(gH323ep.h323Callbacks.onCallEstablished)
1764                gH323ep.h323Callbacks.onCallEstablished(call);
1765          }
1766          ooFreeQ931Message(call->msgctxt, q931Msg);
1767
1768          if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK)) {
1769             if(gH323ep.gkClient->state == GkClientRegistered) {
1770                 ooGkClientSendIRR(gH323ep.gkClient, call);
1771             }
1772          }
1773          break;
1774       case Q931InformationMsg:
1775          OOTRACEINFO3("H.225 Information msg received (%s, %s)\n",
1776                        call->callType, call->callToken);
1777          ooFreeQ931Message(call->msgctxt, q931Msg);
1778          break;
1779
1780
1781       case Q931ReleaseCompleteMsg:/* RELEASE COMPLETE message received */
1782          OOTRACEINFO3("H.225 Release Complete message received (%s, %s)\n",
1783                       call->callType, call->callToken);
1784
1785          call->endTime = (H235TimeStamp) time(NULL);
1786
1787          ooOnReceivedReleaseComplete(call, q931Msg);
1788          
1789          ooFreeQ931Message(call->msgctxt, q931Msg);
1790          break;
1791       case Q931FacilityMsg: 
1792          OOTRACEINFO3("H.225 Facility message Received (%s, %s)\n",
1793                        call->callType, call->callToken);
1794
1795          ooOnReceivedFacility(call, q931Msg); 
1796          ooFreeQ931Message(call->msgctxt, q931Msg);
1797          break;
1798       case Q931StatusMsg:
1799          OOTRACEINFO3("H.225 Status message received (%s, %s)\n",
1800                        call->callType, call->callToken);
1801          ooFreeQ931Message(call->msgctxt, q931Msg);
1802          break;
1803       case Q931StatusEnquiryMsg:
1804          OOTRACEINFO3("H.225 Status Inquiry message Received (%s, %s)\n",
1805                        call->callType, call->callToken);
1806          ooSendStatus(call);
1807          ooFreeQ931Message(call->msgctxt, q931Msg);
1808          break;
1809       case Q931SetupAckMsg:
1810          OOTRACEINFO3("H.225 Setup Ack message received (%s, %s)\n",
1811                        call->callType, call->callToken);
1812          ooFreeQ931Message(call->msgctxt, q931Msg);
1813          break;
1814       case Q931NotifyMsg: 
1815          OOTRACEINFO3("H.225 Notify message Received (%s, %s)\n",
1816                        call->callType, call->callToken);
1817          ooFreeQ931Message(call->msgctxt, q931Msg);
1818          break;
1819       default:
1820          OOTRACEWARN3("Invalid H.225 message type received (%s, %s)\n",
1821                       call->callType, call->callToken);
1822          ooFreeQ931Message(call->msgctxt, q931Msg);
1823    }
1824    return ret;
1825 }
1826
1827 int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
1828 {
1829    H225H323_UU_PDU * pH323UUPdu = NULL;
1830    H225Facility_UUIE * facility = NULL;
1831    int ret;
1832    H225TransportAddress_ipAddress_ip *ip = NULL;
1833    H225TransportAddress_ip6Address_ip *ip6 = NULL;
1834    OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType, 
1835                                                         call->callToken);
1836
1837    ooHandleDisplayIE(call, pQ931Msg);
1838
1839    /* Get Reference to H323_UU_PDU */
1840    if(!pQ931Msg->userInfo)
1841    {
1842       OOTRACEERR3("Error: UserInfo not found in received H.225 Facility "
1843                   "message (%s, %s)\n", call->callType, call->callToken);
1844       return OO_FAILED;
1845    }
1846    pH323UUPdu = &pQ931Msg->userInfo->h323_uu_pdu;
1847    if(!pH323UUPdu)
1848    {
1849       OOTRACEERR1("ERROR: H225H323_UU_PDU absent in incoming facility "
1850                   "message\n");
1851       return OO_FAILED;
1852    }
1853    facility = pH323UUPdu->h323_message_body.u.facility;
1854    if(facility)
1855    {
1856       ooHandleH2250ID(call, &facility->protocolIdentifier);
1857       /* Depending on the reason of facility message handle the message */
1858       if(facility->reason.t == T_H225FacilityReason_transportedInformation)
1859       {
1860          if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1861          {
1862             OOTRACEDBGB3("Handling tunneled messages in Facility. (%s, %s)\n",
1863                call->callType, call->callToken);
1864             ooHandleTunneledH245Messages(call, pH323UUPdu);
1865             OOTRACEDBGB3("Finished handling tunneled messages in Facility."
1866                          "(%s, %s)\n",call->callType, call->callToken);
1867          }
1868          else
1869          {
1870             OOTRACEERR3("ERROR:Tunneled H.245 message received in facility. "
1871                         "Tunneling is disabled at local for this call (%s, %s)\n",
1872                         call->callType, call->callToken);
1873             return OO_FAILED;
1874          }
1875       }
1876       else if(facility->reason.t == T_H225FacilityReason_startH245)
1877       {
1878          OOTRACEINFO3("Remote wants to start a separate H.245 Channel "
1879                       "(%s, %s)\n", call->callType, call->callToken);
1880          /*start H.245 channel*/
1881          ret = ooHandleStartH245FacilityMessage(call, facility);
1882          if(ret != OO_OK)
1883          {
1884             OOTRACEERR3("ERROR: Handling startH245 facility message "
1885                         "(%s, %s)\n", call->callType, call->callToken);
1886             return ret;
1887          }
1888       }
1889       else if(facility->reason.t == T_H225FacilityReason_callForwarded)
1890       {
1891          OOTRACEINFO3("Call Forward Facility message received. (%s, %s)\n",
1892                       call->callType, call->callToken);
1893          if(!facility->m.alternativeAddressPresent && 
1894             !facility->m.alternativeAliasAddressPresent)
1895          {
1896             OOTRACEERR3("Error:No alternative address provided in call forward"
1897                        "facility message.(%s, %s)\n", call->callType, 
1898                         call->callToken);
1899             if(call->callState < OO_CALL_CLEAR)
1900             {
1901                call->callState = OO_CALL_CLEAR;
1902                call->callEndReason = OO_REASON_INVALIDMESSAGE;
1903             }
1904             return OO_OK;
1905          }
1906          call->pCallFwdData = (OOCallFwdData *) memAlloc(call->pctxt, 
1907                                                         sizeof(OOCallFwdData));
1908          if(!call->pCallFwdData)
1909          {
1910             OOTRACEERR3("Error:Memory - ooOnReceivedFacility - pCallFwdData "
1911                         "(%s, %s)\n", call->callType, call->callToken);
1912             return OO_FAILED;
1913          }
1914          call->pCallFwdData->fwdedByRemote = TRUE;
1915          call->pCallFwdData->ip[0]='\0';
1916          call->pCallFwdData->aliases = NULL;
1917          if(facility->m.alternativeAddressPresent)
1918          {
1919           if (call->versionIP == 6) {
1920             if(facility->alternativeAddress.t != 
1921                                            T_H225TransportAddress_ip6Address)
1922             {
1923                OOTRACEERR3("ERROR: Source call signalling address type not ip6 "
1924                            "(%s, %s)\n", call->callType, call->callToken);
1925            
1926                return OO_FAILED;
1927             }
1928
1929             ip6 = &facility->alternativeAddress.u.ip6Address->ip;
1930             inet_ntop(AF_INET6, ip6->data, call->pCallFwdData->ip, INET6_ADDRSTRLEN);
1931             call->pCallFwdData->port =  
1932                                facility->alternativeAddress.u.ip6Address->port;
1933           } else {
1934             if(facility->alternativeAddress.t != 
1935                                            T_H225TransportAddress_ipAddress)
1936             {
1937                OOTRACEERR3("ERROR: Source call signalling address type not ip "
1938                            "(%s, %s)\n", call->callType, call->callToken);
1939            
1940                return OO_FAILED;
1941             }
1942
1943             ip = &facility->alternativeAddress.u.ipAddress->ip;
1944             sprintf(call->pCallFwdData->ip, "%d.%d.%d.%d", ip->data[0], 
1945                                        ip->data[1], ip->data[2], ip->data[3]);
1946             call->pCallFwdData->port =  
1947                                facility->alternativeAddress.u.ipAddress->port;
1948           }
1949          }
1950
1951          if(facility->m.alternativeAliasAddressPresent)
1952          {
1953             ooH323RetrieveAliases(call, &facility->alternativeAliasAddress, 
1954                                   &call->pCallFwdData->aliases);
1955          }
1956          /* Now we have to clear the current call and make a new call to
1957             fwded location*/
1958          if(call->callState < OO_CALL_CLEAR)
1959          {
1960             call->callState = OO_CALL_CLEAR;
1961             call->callEndReason = OO_REASON_REMOTE_FWDED;
1962          }
1963          else{
1964             OOTRACEERR3("Error:Can't forward call as it is being cleared."
1965                         " (%s, %s)\n", call->callType, call->callToken);
1966            return OO_OK;
1967          }
1968       }
1969       else if(facility->reason.t == T_H225FacilityReason_forwardedElements)
1970       {
1971          OOTRACEINFO3("Handling fast start in forwardedElem facility for "
1972                       "(%s, %s)\n", call->callType, call->callToken);
1973          /*start H.245 channel*/
1974          ret = ooHandleFastStart(call, facility);
1975          if(ret != OO_OK)
1976          {
1977             OOTRACEERR3("ERROR: Handling transportedInformation facility message "
1978                         "(%s, %s)\n", call->callType, call->callToken);
1979             return ret;
1980          }
1981       }
1982       else{
1983          OOTRACEINFO3("Unhandled Facility reason type received (%s, %s)\n", 
1984                        call->callType, call->callToken);
1985       }
1986    }
1987    else{ /* Empty facility message Check for tunneling */
1988       if (pH323UUPdu->h323_message_body.t == 
1989           T_H225H323_UU_PDU_h323_message_body_empty) {
1990       OOTRACEDBGB3("Handling tunneled messages in empty Facility message."
1991                    " (%s, %s)\n", call->callType, call->callToken);
1992       ooHandleTunneledH245Messages(call, pH323UUPdu);
1993       OOTRACEDBGB3("Finished handling tunneled messages in empty Facility "
1994                    "message. (%s, %s)\n", call->callType, call->callToken);
1995       }
1996    }
1997    
1998    return OO_OK;
1999 }
2000
2001 int ooHandleStartH245FacilityMessage
2002    (OOH323CallData *call, H225Facility_UUIE *facility)
2003 {
2004    H225TransportAddress_ipAddress *ipAddress = NULL;
2005    H225TransportAddress_ip6Address *ip6Address = NULL;
2006    int ret;
2007    
2008    /* Extract H245 address */
2009    if(!facility->m.h245AddressPresent)
2010    {
2011       OOTRACEERR3("ERROR: startH245 facility message received with no h245 "
2012                   "address (%s, %s)\n", call->callType, call->callToken);
2013       return OO_FAILED;
2014    }
2015    if (call->versionIP == 6) {
2016     if(facility->h245Address.t != T_H225TransportAddress_ip6Address)
2017     {
2018       OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
2019                "facility message (%s, %s)\n", call->callType, call->callToken);
2020       return OO_FAILED;
2021     }
2022     ip6Address = facility->h245Address.u.ip6Address;
2023     if(!ip6Address)
2024     {
2025       OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip6 "
2026                   "address found. (%s, %s)\n", call->callType, call->callToken);
2027       return OO_FAILED;
2028     }
2029     inet_ntop(AF_INET6, ip6Address->ip.data, call->remoteIP, INET6_ADDRSTRLEN);
2030     call->remoteH245Port = ip6Address->port;
2031    } else {
2032     if(facility->h245Address.t != T_H225TransportAddress_ipAddress)
2033     {
2034       OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
2035                "facility message (%s, %s)\n", call->callType, call->callToken);
2036       return OO_FAILED;
2037     }
2038     ipAddress = facility->h245Address.u.ipAddress;
2039     if(!ipAddress)
2040     {
2041       OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip "
2042                   "address found. (%s, %s)\n", call->callType, call->callToken);
2043       return OO_FAILED;
2044     }
2045    
2046     sprintf(call->remoteIP, "%d.%d.%d.%d", ipAddress->ip.data[0],
2047                                           ipAddress->ip.data[1],
2048                                           ipAddress->ip.data[2],
2049                                           ipAddress->ip.data[3]);
2050     call->remoteH245Port = ipAddress->port;
2051    }
2052
2053    /* disable tunneling for this call */
2054    OO_CLRFLAG (call->flags, OO_M_TUNNELING);
2055
2056    /*Establish an H.245 connection */
2057    if (!call->pH245Channel) {
2058     ret = ooCreateH245Connection(call);
2059     if(ret != OO_OK)
2060     {
2061       OOTRACEERR3("ERROR: Failed to establish an H.245 connection with remote"
2062                   " endpoint (%s, %s)\n", call->callType, call->callToken);
2063       return ret;
2064     }
2065    } else {
2066      OOTRACEINFO3("INFO: H.245 connection already established with remote"
2067                   " endpoint (%s, %s)\n", call->callType, call->callToken);
2068    }
2069    ooSendTCSandMSD(call);
2070    return OO_OK;
2071 }
2072
2073 int ooHandleTunneledH245Messages
2074    (OOH323CallData *call, H225H323_UU_PDU * pH323UUPdu)
2075 {
2076    H245Message *pmsg;
2077    OOCTXT *pctxt = call->msgctxt;
2078    int ret=0,i=0;
2079    
2080    OOTRACEDBGC3("Checking for tunneled H.245 messages (%s, %s)\n", 
2081                  call->callType, call->callToken);
2082
2083    /* Check whether there are tunneled messages */  
2084    if(pH323UUPdu->m.h245TunnelingPresent)
2085    {
2086       if(pH323UUPdu->h245Tunneling)
2087       {
2088          OOTRACEDBGB4("Total number of tunneled H245 messages are %d.(%s, %s)"
2089                       "\n", (int)pH323UUPdu->h245Control.n, call->callType, 
2090                       call->callToken);
2091          for(i=0; i< (int)pH323UUPdu->h245Control.n; i++)
2092          {
2093             OOTRACEDBGC5("Retrieving %d of %d tunneled H.245 messages."
2094                          "(%s, %s)\n",i+1, pH323UUPdu->h245Control.n,
2095                          call->callType, call->callToken);
2096             pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
2097             if(!pmsg)
2098             {
2099                OOTRACEERR3("Error:Memory - ooHandleH245TunneledMessages - pmsg"
2100                           "(%s, %s)\n", call->callType, call->callToken);
2101                return OO_FAILED;
2102             }
2103
2104             setPERBuffer(pctxt, 
2105                          (ASN1OCTET*)pH323UUPdu->h245Control.elem[i].data,
2106                          pH323UUPdu->h245Control.elem[i].numocts, 1);  
2107
2108             initializePrintHandler(&printHandler, "Tunneled H.245 Message");
2109             memset(pmsg, 0, sizeof(H245Message));
2110             /* Set event handler */
2111             setEventHandler (pctxt, &printHandler);
2112             OOTRACEDBGC4("Decoding %d tunneled H245 message. (%s, %s)\n", 
2113                           i+1, call->callType, call->callToken);
2114             ret = asn1PD_H245MultimediaSystemControlMessage(pctxt, 
2115                                                             &(pmsg->h245Msg));
2116             if(ret != ASN_OK)
2117             {
2118                OOTRACEERR3("Error decoding H245 message (%s, %s)\n", 
2119                             call->callType, call->callToken);
2120                ooFreeH245Message(call,pmsg);
2121                return OO_FAILED;
2122             }
2123             finishPrint();
2124             removeEventHandler (pctxt);
2125             ooHandleH245Message(call, pmsg);
2126             memFreePtr(pctxt, pmsg);
2127             pmsg = NULL;
2128          }/* End of For loop */
2129       }/* End of if(h245Tunneling) */
2130    }
2131    return OO_OK;
2132 }
2133
2134 int ooH323RetrieveAliases
2135    (OOH323CallData *call, H225_SeqOfH225AliasAddress *pAddresses, 
2136     OOAliases **aliasList)
2137 {
2138    int i=0,j=0,k=0;
2139    DListNode* pNode=NULL;
2140    H225AliasAddress *pAliasAddress=NULL;
2141    OOAliases *newAlias=NULL;
2142    H225TransportAddress *pTransportAddrss=NULL;
2143
2144    if(!pAddresses)
2145    {
2146       OOTRACEWARN3("Warn:No Aliases present (%s, %s)\n", call->callType, 
2147                     call->callToken);
2148       return OO_OK;
2149    }
2150    /* check for aliases */
2151    if(pAddresses->count<=0)
2152       return OO_OK;
2153    
2154    for(i=0; i<(int)pAddresses->count; i++)
2155    {
2156       pNode = dListFindByIndex (pAddresses, i);
2157
2158       if(!pNode)
2159          continue;
2160
2161       pAliasAddress = (H225AliasAddress*)pNode->data;
2162
2163       if(!pAliasAddress)
2164          continue;
2165
2166       newAlias = (OOAliases*)memAlloc(call->pctxt, sizeof(OOAliases));
2167       if(!newAlias)
2168       {
2169          OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - newAlias "
2170                      "(%s, %s)\n", call->callType, call->callToken);
2171          return OO_FAILED;
2172       }
2173       memset(newAlias, 0, sizeof(OOAliases));
2174       switch(pAliasAddress->t)
2175       {
2176       case T_H225AliasAddress_dialedDigits:
2177          newAlias->type = T_H225AliasAddress_dialedDigits;
2178          newAlias->value = (char*) memAlloc(call->pctxt, 
2179                          strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2180          if(!newAlias->value)
2181          {
2182             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2183                         "newAlias->value(dialedDigits) (%s, %s)\n", 
2184                          call->callType, call->callToken);
2185             memFreePtr(call->pctxt, newAlias);  
2186             return OO_FAILED;
2187          }
2188
2189          memcpy(newAlias->value, pAliasAddress->u.dialedDigits,
2190                            strlen(pAliasAddress->u.dialedDigits)*sizeof(char));
2191          newAlias->value[strlen(pAliasAddress->u.dialedDigits)*sizeof(char)]='\0';
2192          break;
2193       case T_H225AliasAddress_h323_ID:
2194          newAlias->type = T_H225AliasAddress_h323_ID;
2195          newAlias->value = (char*)memAlloc(call->pctxt, 
2196                          (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2197          if(!newAlias->value)
2198          {
2199             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2200                         "newAlias->value(h323id) (%s, %s)\n", call->callType, 
2201                          call->callToken);
2202             memFreePtr(call->pctxt, newAlias);  
2203             return OO_FAILED;
2204          }
2205
2206          for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2207          {
2208             if(pAliasAddress->u.h323_ID.data[j] < 256)
2209             {
2210                newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2211             }
2212          }
2213          newAlias->value[k] = '\0';
2214          break;   
2215       case T_H225AliasAddress_url_ID:
2216          newAlias->type = T_H225AliasAddress_url_ID;
2217          newAlias->value = (char*)memAlloc(call->pctxt,
2218                               strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2219          if(!newAlias->value)
2220          {
2221             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2222                         "newAlias->value(urlid) (%s, %s)\n", call->callType, 
2223                          call->callToken);
2224             memFreePtr(call->pctxt, newAlias);  
2225             return OO_FAILED;
2226          }
2227
2228          memcpy(newAlias->value, pAliasAddress->u.url_ID,
2229                                strlen(pAliasAddress->u.url_ID)*sizeof(char));
2230          newAlias->value[strlen(pAliasAddress->u.url_ID)*sizeof(char)]='\0';
2231          break;
2232       case T_H225AliasAddress_transportID:
2233         newAlias->type = T_H225AliasAddress_transportID;
2234         pTransportAddrss = pAliasAddress->u.transportID;
2235         if(pTransportAddrss->t == T_H225TransportAddress_ip6Address) {
2236          /* hopefully ip:port value can't exceed more than 30 
2237             characters */
2238          newAlias->value = (char*)memAlloc(call->pctxt, 
2239                                                       INET6_ADDRSTRLEN*sizeof(char)*2);
2240          inet_ntop(AF_INET6, pTransportAddrss->u.ip6Address->ip.data, newAlias->value, INET6_ADDRSTRLEN);
2241          sprintf(newAlias->value+strlen(newAlias->value), ":%d", pTransportAddrss->u.ip6Address->port);
2242         } else if(pTransportAddrss->t == T_H225TransportAddress_ipAddress) {
2243          /* hopefully ip:port value can't exceed more than 30 
2244             characters */
2245          newAlias->value = (char*)memAlloc(call->pctxt, 
2246                                                       30*sizeof(char));
2247          sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2248                                   pTransportAddrss->u.ipAddress->ip.data[0],
2249                                   pTransportAddrss->u.ipAddress->ip.data[1],
2250                                   pTransportAddrss->u.ipAddress->ip.data[2],
2251                                   pTransportAddrss->u.ipAddress->ip.data[3],
2252                                   pTransportAddrss->u.ipAddress->port);
2253         } else {
2254          OOTRACEERR3("Error:Alias transportID not an IP4 nor IP6 address"
2255                      "(%s, %s)\n", call->callType, call->callToken);
2256          memFreePtr(call->pctxt, newAlias);
2257         }
2258         break;
2259       case T_H225AliasAddress_email_ID:
2260          newAlias->type = T_H225AliasAddress_email_ID;
2261          newAlias->value = (char*)memAlloc(call->pctxt, 
2262                              strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2263          if(!newAlias->value)
2264          {
2265             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2266                         "newAlias->value(emailid) (%s, %s)\n", call->callType, 
2267                          call->callToken);
2268             memFreePtr(call->pctxt, newAlias);  
2269             return OO_FAILED;
2270          }
2271
2272          memcpy(newAlias->value, pAliasAddress->u.email_ID,
2273                               strlen(pAliasAddress->u.email_ID)*sizeof(char));
2274          newAlias->value[strlen(pAliasAddress->u.email_ID)*sizeof(char)]='\0';
2275          break;
2276       default:
2277          OOTRACEERR3("Error:Unhandled Alias type (%s, %s)\n", 
2278                        call->callType, call->callToken);
2279          memFreePtr(call->pctxt, newAlias);
2280          continue;
2281       }
2282
2283       newAlias->next = *aliasList;
2284       *aliasList = newAlias;
2285
2286       newAlias = NULL;
2287      
2288      pAliasAddress = NULL;
2289      pNode = NULL;
2290    }/* endof: for */
2291    return OO_OK;
2292 }
2293
2294
2295 int ooPopulatePrefixList(OOCTXT *pctxt, OOAliases *pAliases,
2296                            H225_SeqOfH225SupportedPrefix *pPrefixList )
2297 {
2298    H225SupportedPrefix *pPrefixEntry=NULL;
2299    OOAliases * pAlias=NULL;
2300    ASN1BOOL bValid=FALSE;
2301
2302    dListInit(pPrefixList);
2303    if(pAliases)
2304    {
2305       pAlias = pAliases;
2306       while(pAlias)
2307       {
2308          pPrefixEntry = NULL;
2309          switch(pAlias->type)
2310          {
2311          case T_H225AliasAddress_dialedDigits:
2312             pPrefixEntry = (H225SupportedPrefix *)memAlloc(pctxt, 
2313                                                      sizeof(H225SupportedPrefix));
2314             if(!pPrefixEntry) {
2315                 OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - pAliasEntry\n");
2316                 return OO_FAILED;
2317             }
2318             pPrefixEntry->prefix.t = T_H225AliasAddress_dialedDigits;
2319             pPrefixEntry->prefix.u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2320                                                      strlen(pAlias->value)+1);
2321             if(!pPrefixEntry->prefix.u.dialedDigits) {
2322                OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - "
2323                            "dialedDigits\n");
2324                memFreePtr(pctxt, pPrefixEntry);
2325                return OO_FAILED;
2326             }
2327             strcpy(*(char**)&pPrefixEntry->prefix.u.dialedDigits, pAlias->value);
2328             bValid = TRUE;
2329             break;
2330          default:
2331             bValid = FALSE;                  
2332          }
2333          
2334          if(bValid)
2335             dListAppend( pctxt, pPrefixList, (void*)pPrefixEntry );
2336          
2337          pAlias = pAlias->next;
2338       }
2339    }
2340    return OO_OK;
2341 }
2342 int ooPopulateAliasList(OOCTXT *pctxt, OOAliases *pAliases,
2343                            H225_SeqOfH225AliasAddress *pAliasList, int pAliasType)
2344 {
2345    H225AliasAddress *pAliasEntry=NULL;
2346    OOAliases * pAlias=NULL;
2347    ASN1BOOL bValid=FALSE;
2348    int i = 0;
2349
2350    dListInit(pAliasList);
2351    if(pAliases)
2352    {
2353       pAlias = pAliases;
2354       while(pAlias)
2355       {
2356          if (pAlias->value[0] == 0) {
2357           pAlias = pAlias->next;
2358           continue;
2359          }
2360          pAliasEntry = (H225AliasAddress*)memAlloc(pctxt, 
2361                                                      sizeof(H225AliasAddress));
2362          if(!pAliasEntry)
2363          {
2364             OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - pAliasEntry\n");
2365             return OO_FAILED;
2366          }
2367
2368          if (pAliasType && pAlias->type != pAliasType) {
2369                 pAlias = pAlias->next;
2370                 continue;
2371          }
2372          switch(pAlias->type)
2373          {
2374             case T_H225AliasAddress_dialedDigits:
2375              pAliasEntry->t = T_H225AliasAddress_dialedDigits;
2376              pAliasEntry->u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2377                                                      strlen(pAlias->value)+1);
2378              if(!pAliasEntry->u.dialedDigits)
2379              {
2380                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - "
2381                            "dialedDigits\n");
2382                memFreePtr(pctxt, pAliasEntry);
2383                return OO_FAILED;
2384              }
2385              strcpy(*(char**)&pAliasEntry->u.dialedDigits, pAlias->value);
2386              bValid = TRUE;
2387             break;
2388          case T_H225AliasAddress_h323_ID:
2389             pAliasEntry->t = T_H225AliasAddress_h323_ID;
2390             pAliasEntry->u.h323_ID.nchars = strlen(pAlias->value);
2391             pAliasEntry->u.h323_ID.data = (ASN116BITCHAR*)memAllocZ
2392                      (pctxt, strlen(pAlias->value)*sizeof(ASN116BITCHAR));
2393             
2394             if(!pAliasEntry->u.h323_ID.data)
2395             {
2396                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - h323_id\n");
2397                memFreePtr(pctxt, pAliasEntry);
2398                return OO_FAILED;
2399             }
2400             for(i=0; *(pAlias->value+i) != '\0'; i++)
2401                pAliasEntry->u.h323_ID.data[i] =(ASN116BITCHAR)pAlias->value[i];
2402             bValid = TRUE;
2403             break;
2404          case T_H225AliasAddress_url_ID:
2405             pAliasEntry->t = T_H225AliasAddress_url_ID;
2406             pAliasEntry->u.url_ID = (ASN1IA5String)memAlloc(pctxt, 
2407                                                      strlen(pAlias->value)+1);
2408             if(!pAliasEntry->u.url_ID)
2409             {
2410                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - url_id\n");
2411                memFreePtr(pctxt, pAliasEntry);               
2412                return OO_FAILED;
2413             }
2414             strcpy(*(char**)&pAliasEntry->u.url_ID, pAlias->value);
2415             bValid = TRUE;
2416             break;
2417          case T_H225AliasAddress_email_ID:
2418             pAliasEntry->t = T_H225AliasAddress_email_ID;
2419             pAliasEntry->u.email_ID = (ASN1IA5String)memAlloc(pctxt, 
2420                                                      strlen(pAlias->value)+1);
2421             if(!pAliasEntry->u.email_ID)
2422             {
2423                OOTRACEERR1("ERROR: Failed to allocate memory for EmailID "
2424                            "alias entry \n");
2425                return OO_FAILED;
2426             }
2427             strcpy(*(char**)&pAliasEntry->u.email_ID, pAlias->value);
2428             bValid = TRUE;
2429             break;
2430          default:
2431             OOTRACEERR1("ERROR: Unhandled alias type\n");
2432             bValid = FALSE;                  
2433          }
2434          
2435          if(bValid)
2436             dListAppend( pctxt, pAliasList, (void*)pAliasEntry );
2437          else
2438             memFreePtr(pctxt, pAliasEntry);
2439          
2440          pAlias = pAlias->next;
2441       }
2442    }
2443    return OO_OK;
2444 }
2445
2446
2447 OOAliases* ooH323GetAliasFromList(OOAliases *aliasList, int type, char *value)
2448 {
2449
2450    OOAliases *pAlias = NULL;
2451
2452    if(!aliasList)
2453    {
2454       OOTRACEDBGC1("No alias List to search\n");
2455       return NULL;
2456    }
2457
2458    pAlias = aliasList;
2459
2460    while(pAlias)
2461    {
2462      if(type != 0 && value) { /* Search by type and value */
2463          if(pAlias->type == type && !strcmp(pAlias->value, value))
2464          {
2465             return pAlias;
2466          }
2467       }
2468       else if(type != 0 && !value) {/* search by type */
2469          if(pAlias->type == type)
2470             return pAlias;
2471       }
2472       else if(type == 0 && value) {/* search by value */
2473          if(!strcmp(pAlias->value, value))
2474             return pAlias;
2475       }
2476       else {
2477          OOTRACEDBGC1("No criteria to search the alias list\n");
2478          return NULL;
2479       }
2480       pAlias = pAlias->next;
2481    }
2482
2483    return NULL;
2484 }
2485
2486 OOAliases* ooH323AddAliasToList
2487 (OOAliases **pAliasList, OOCTXT *pctxt, H225AliasAddress *pAliasAddress)
2488 {
2489    int j=0,k=0;
2490    OOAliases *newAlias=NULL;
2491    H225TransportAddress *pTransportAddrss=NULL;
2492    
2493    newAlias = (OOAliases*) memAlloc(pctxt, sizeof(OOAliases));
2494    if(!newAlias)
2495    {
2496       OOTRACEERR1("Error: Failed to allocate memory for new alias to be added to the alias list\n");
2497       return NULL;
2498    }
2499    memset(newAlias, 0, sizeof(OOAliases));
2500
2501    switch(pAliasAddress->t)
2502    {
2503    case T_H225AliasAddress_dialedDigits:
2504       newAlias->type = T_H225AliasAddress_dialedDigits;
2505       newAlias->value = (char*) memAlloc(pctxt, strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2506       strcpy(newAlias->value, pAliasAddress->u.dialedDigits);
2507       break;
2508    case T_H225AliasAddress_h323_ID:
2509       newAlias->type = T_H225AliasAddress_h323_ID;
2510       newAlias->value = (char*)memAlloc(pctxt, 
2511                            (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2512
2513       for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2514       {
2515          if(pAliasAddress->u.h323_ID.data[j] < 256)
2516          {
2517             newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2518          }
2519       }
2520       newAlias->value[k] = '\0';
2521       break;   
2522    case T_H225AliasAddress_url_ID:
2523       newAlias->type = T_H225AliasAddress_url_ID;
2524       newAlias->value = (char*)memAlloc(pctxt,
2525                             strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2526
2527       strcpy(newAlias->value, pAliasAddress->u.url_ID);
2528       break;
2529    case T_H225AliasAddress_transportID:
2530       newAlias->type = T_H225AliasAddress_transportID;
2531       pTransportAddrss = pAliasAddress->u.transportID;
2532       if(pTransportAddrss->t == T_H225TransportAddress_ip6Address) {
2533        /* hopefully ip:port value can't exceed more than 30 
2534          characters */
2535        newAlias->value = (char*)memAlloc(pctxt, 
2536                                               INET6_ADDRSTRLEN*sizeof(char)*2);
2537        inet_ntop(AF_INET6, pTransportAddrss->u.ip6Address->ip.data, newAlias->value, INET6_ADDRSTRLEN);
2538        sprintf(newAlias->value+strlen(newAlias->value), ":%d", pTransportAddrss->u.ip6Address->port);
2539       } else if(pTransportAddrss->t == T_H225TransportAddress_ipAddress) {
2540        /* hopefully ip:port value can't exceed more than 30 
2541          characters */
2542        newAlias->value = (char*)memAlloc(pctxt, 
2543                                               30*sizeof(char));
2544        sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2545                                pTransportAddrss->u.ipAddress->ip.data[0],
2546                                pTransportAddrss->u.ipAddress->ip.data[1],
2547                                pTransportAddrss->u.ipAddress->ip.data[2],
2548                                pTransportAddrss->u.ipAddress->ip.data[3],
2549                                pTransportAddrss->u.ipAddress->port);
2550       } else {
2551        OOTRACEERR1("Error:Alias transportID not an IP4 nor IP6 address\n");
2552        memFreePtr(pctxt, newAlias);
2553        return NULL;
2554       }
2555       break;
2556    case T_H225AliasAddress_email_ID:
2557       newAlias->type = T_H225AliasAddress_email_ID;
2558       newAlias->value = (char*)memAlloc(pctxt, 
2559                  strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2560
2561       strcpy(newAlias->value, pAliasAddress->u.email_ID);
2562       break;
2563    default:
2564       OOTRACEERR1("Error:Unhandled Alias type \n");
2565       memFreePtr(pctxt, newAlias);
2566       return NULL;
2567
2568    }
2569    newAlias->next = *pAliasList;
2570    *pAliasList= newAlias;
2571    return newAlias;
2572 }
2573
2574 int ooH323GetIpPortFromH225TransportAddress(struct OOH323CallData *call, 
2575    H225TransportAddress *h225Address, char *ip, int *port)
2576 {
2577    if (call->versionIP == 6) {
2578     if(h225Address->t != T_H225TransportAddress_ip6Address)
2579     {
2580       OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
2581                    call->callToken);
2582       return OO_FAILED;
2583     }
2584     inet_ntop(AF_INET6, h225Address->u.ip6Address->ip.data, ip, INET6_ADDRSTRLEN);
2585     *port = h225Address->u.ip6Address->port;
2586     return OO_OK;
2587    }
2588    if(h225Address->t != T_H225TransportAddress_ipAddress)
2589    {
2590       OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
2591                    call->callToken);
2592       return OO_FAILED;
2593    }
2594    sprintf(ip, "%d.%d.%d.%d", 
2595               h225Address->u.ipAddress->ip.data[0], 
2596               h225Address->u.ipAddress->ip.data[1],
2597               h225Address->u.ipAddress->ip.data[2],
2598               h225Address->u.ipAddress->ip.data[3]);
2599    *port = h225Address->u.ipAddress->port;
2600    return OO_OK;
2601 }