Merged revisions 333961-333962 via svnmerge from
[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          ooFreeQ931Message(call->msgctxt, q931Msg);
1807          break;
1808       case Q931SetupAckMsg:
1809          OOTRACEINFO3("H.225 Setup Ack message received (%s, %s)\n",
1810                        call->callType, call->callToken);
1811          ooFreeQ931Message(call->msgctxt, q931Msg);
1812          break;
1813       case Q931NotifyMsg: 
1814          OOTRACEINFO3("H.225 Notify message Received (%s, %s)\n",
1815                        call->callType, call->callToken);
1816          ooFreeQ931Message(call->msgctxt, q931Msg);
1817          break;
1818       default:
1819          OOTRACEWARN3("Invalid H.225 message type received (%s, %s)\n",
1820                       call->callType, call->callToken);
1821          ooFreeQ931Message(call->msgctxt, q931Msg);
1822    }
1823    return ret;
1824 }
1825
1826 int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
1827 {
1828    H225H323_UU_PDU * pH323UUPdu = NULL;
1829    H225Facility_UUIE * facility = NULL;
1830    int ret;
1831    H225TransportAddress_ipAddress_ip *ip = NULL;
1832    H225TransportAddress_ip6Address_ip *ip6 = NULL;
1833    OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType, 
1834                                                         call->callToken);
1835
1836    ooHandleDisplayIE(call, pQ931Msg);
1837
1838    /* Get Reference to H323_UU_PDU */
1839    if(!pQ931Msg->userInfo)
1840    {
1841       OOTRACEERR3("Error: UserInfo not found in received H.225 Facility "
1842                   "message (%s, %s)\n", call->callType, call->callToken);
1843       return OO_FAILED;
1844    }
1845    pH323UUPdu = &pQ931Msg->userInfo->h323_uu_pdu;
1846    if(!pH323UUPdu)
1847    {
1848       OOTRACEERR1("ERROR: H225H323_UU_PDU absent in incoming facility "
1849                   "message\n");
1850       return OO_FAILED;
1851    }
1852    facility = pH323UUPdu->h323_message_body.u.facility;
1853    if(facility)
1854    {
1855       ooHandleH2250ID(call, facility->protocolIdentifier);
1856       /* Depending on the reason of facility message handle the message */
1857       if(facility->reason.t == T_H225FacilityReason_transportedInformation)
1858       {
1859          if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1860          {
1861             OOTRACEDBGB3("Handling tunneled messages in Facility. (%s, %s)\n",
1862                call->callType, call->callToken);
1863             ooHandleTunneledH245Messages(call, pH323UUPdu);
1864             OOTRACEDBGB3("Finished handling tunneled messages in Facility."
1865                          "(%s, %s)\n",call->callType, call->callToken);
1866          }
1867          else
1868          {
1869             OOTRACEERR3("ERROR:Tunneled H.245 message received in facility. "
1870                         "Tunneling is disabled at local for this call (%s, %s)\n",
1871                         call->callType, call->callToken);
1872             return OO_FAILED;
1873          }
1874       }
1875       else if(facility->reason.t == T_H225FacilityReason_startH245)
1876       {
1877          OOTRACEINFO3("Remote wants to start a separate H.245 Channel "
1878                       "(%s, %s)\n", call->callType, call->callToken);
1879          /*start H.245 channel*/
1880          ret = ooHandleStartH245FacilityMessage(call, facility);
1881          if(ret != OO_OK)
1882          {
1883             OOTRACEERR3("ERROR: Handling startH245 facility message "
1884                         "(%s, %s)\n", call->callType, call->callToken);
1885             return ret;
1886          }
1887       }
1888       else if(facility->reason.t == T_H225FacilityReason_callForwarded)
1889       {
1890          OOTRACEINFO3("Call Forward Facility message received. (%s, %s)\n",
1891                       call->callType, call->callToken);
1892          if(!facility->m.alternativeAddressPresent && 
1893             !facility->m.alternativeAliasAddressPresent)
1894          {
1895             OOTRACEERR3("Error:No alternative address provided in call forward"
1896                        "facility message.(%s, %s)\n", call->callType, 
1897                         call->callToken);
1898             if(call->callState < OO_CALL_CLEAR)
1899             {
1900                call->callState = OO_CALL_CLEAR;
1901                call->callEndReason = OO_REASON_INVALIDMESSAGE;
1902             }
1903             return OO_OK;
1904          }
1905          call->pCallFwdData = (OOCallFwdData *) memAlloc(call->pctxt, 
1906                                                         sizeof(OOCallFwdData));
1907          if(!call->pCallFwdData)
1908          {
1909             OOTRACEERR3("Error:Memory - ooOnReceivedFacility - pCallFwdData "
1910                         "(%s, %s)\n", call->callType, call->callToken);
1911             return OO_FAILED;
1912          }
1913          call->pCallFwdData->fwdedByRemote = TRUE;
1914          call->pCallFwdData->ip[0]='\0';
1915          call->pCallFwdData->aliases = NULL;
1916          if(facility->m.alternativeAddressPresent)
1917          {
1918           if (call->versionIP == 6) {
1919             if(facility->alternativeAddress.t != 
1920                                            T_H225TransportAddress_ip6Address)
1921             {
1922                OOTRACEERR3("ERROR: Source call signalling address type not ip6 "
1923                            "(%s, %s)\n", call->callType, call->callToken);
1924            
1925                return OO_FAILED;
1926             }
1927
1928             ip6 = &facility->alternativeAddress.u.ip6Address->ip;
1929             inet_ntop(AF_INET6, ip6->data, call->pCallFwdData->ip, INET6_ADDRSTRLEN);
1930             call->pCallFwdData->port =  
1931                                facility->alternativeAddress.u.ip6Address->port;
1932           } else {
1933             if(facility->alternativeAddress.t != 
1934                                            T_H225TransportAddress_ipAddress)
1935             {
1936                OOTRACEERR3("ERROR: Source call signalling address type not ip "
1937                            "(%s, %s)\n", call->callType, call->callToken);
1938            
1939                return OO_FAILED;
1940             }
1941
1942             ip = &facility->alternativeAddress.u.ipAddress->ip;
1943             sprintf(call->pCallFwdData->ip, "%d.%d.%d.%d", ip->data[0], 
1944                                        ip->data[1], ip->data[2], ip->data[3]);
1945             call->pCallFwdData->port =  
1946                                facility->alternativeAddress.u.ipAddress->port;
1947           }
1948          }
1949
1950          if(facility->m.alternativeAliasAddressPresent)
1951          {
1952             ooH323RetrieveAliases(call, &facility->alternativeAliasAddress, 
1953                                   &call->pCallFwdData->aliases);
1954          }
1955          /* Now we have to clear the current call and make a new call to
1956             fwded location*/
1957          if(call->callState < OO_CALL_CLEAR)
1958          {
1959             call->callState = OO_CALL_CLEAR;
1960             call->callEndReason = OO_REASON_REMOTE_FWDED;
1961          }
1962          else{
1963             OOTRACEERR3("Error:Can't forward call as it is being cleared."
1964                         " (%s, %s)\n", call->callType, call->callToken);
1965            return OO_OK;
1966          }
1967       }
1968       else if(facility->reason.t == T_H225FacilityReason_forwardedElements)
1969       {
1970          OOTRACEINFO3("Handling fast start in forwardedElem facility for "
1971                       "(%s, %s)\n", call->callType, call->callToken);
1972          /*start H.245 channel*/
1973          ret = ooHandleFastStart(call, facility);
1974          if(ret != OO_OK)
1975          {
1976             OOTRACEERR3("ERROR: Handling transportedInformation facility message "
1977                         "(%s, %s)\n", call->callType, call->callToken);
1978             return ret;
1979          }
1980       }
1981       else{
1982          OOTRACEINFO3("Unhandled Facility reason type received (%s, %s)\n", 
1983                        call->callType, call->callToken);
1984       }
1985    }
1986    else{ /* Empty facility message Check for tunneling */
1987       if (pH323UUPdu->h323_message_body.t == 
1988           T_H225H323_UU_PDU_h323_message_body_empty) {
1989       OOTRACEDBGB3("Handling tunneled messages in empty Facility message."
1990                    " (%s, %s)\n", call->callType, call->callToken);
1991       ooHandleTunneledH245Messages(call, pH323UUPdu);
1992       OOTRACEDBGB3("Finished handling tunneled messages in empty Facility "
1993                    "message. (%s, %s)\n", call->callType, call->callToken);
1994       }
1995    }
1996    
1997    return OO_OK;
1998 }
1999
2000 int ooHandleStartH245FacilityMessage
2001    (OOH323CallData *call, H225Facility_UUIE *facility)
2002 {
2003    H225TransportAddress_ipAddress *ipAddress = NULL;
2004    H225TransportAddress_ip6Address *ip6Address = NULL;
2005    int ret;
2006    
2007    /* Extract H245 address */
2008    if(!facility->m.h245AddressPresent)
2009    {
2010       OOTRACEERR3("ERROR: startH245 facility message received with no h245 "
2011                   "address (%s, %s)\n", call->callType, call->callToken);
2012       return OO_FAILED;
2013    }
2014    if (call->versionIP == 6) {
2015     if(facility->h245Address.t != T_H225TransportAddress_ip6Address)
2016     {
2017       OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
2018                "facility message (%s, %s)\n", call->callType, call->callToken);
2019       return OO_FAILED;
2020     }
2021     ip6Address = facility->h245Address.u.ip6Address;
2022     if(!ip6Address)
2023     {
2024       OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip6 "
2025                   "address found. (%s, %s)\n", call->callType, call->callToken);
2026       return OO_FAILED;
2027     }
2028     inet_ntop(AF_INET6, ip6Address->ip.data, call->remoteIP, INET6_ADDRSTRLEN);
2029     call->remoteH245Port = ip6Address->port;
2030    } else {
2031     if(facility->h245Address.t != T_H225TransportAddress_ipAddress)
2032     {
2033       OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
2034                "facility message (%s, %s)\n", call->callType, call->callToken);
2035       return OO_FAILED;
2036     }
2037     ipAddress = facility->h245Address.u.ipAddress;
2038     if(!ipAddress)
2039     {
2040       OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip "
2041                   "address found. (%s, %s)\n", call->callType, call->callToken);
2042       return OO_FAILED;
2043     }
2044    
2045     sprintf(call->remoteIP, "%d.%d.%d.%d", ipAddress->ip.data[0],
2046                                           ipAddress->ip.data[1],
2047                                           ipAddress->ip.data[2],
2048                                           ipAddress->ip.data[3]);
2049     call->remoteH245Port = ipAddress->port;
2050    }
2051
2052    /* disable tunneling for this call */
2053    OO_CLRFLAG (call->flags, OO_M_TUNNELING);
2054
2055    /*Establish an H.245 connection */
2056    if (!call->pH245Channel) {
2057     ret = ooCreateH245Connection(call);
2058     if(ret != OO_OK)
2059     {
2060       OOTRACEERR3("ERROR: Failed to establish an H.245 connection with remote"
2061                   " endpoint (%s, %s)\n", call->callType, call->callToken);
2062       return ret;
2063     }
2064    } else {
2065      OOTRACEINFO3("INFO: H.245 connection already established with remote"
2066                   " endpoint (%s, %s)\n", call->callType, call->callToken);
2067    }
2068    ooSendTCSandMSD(call);
2069    return OO_OK;
2070 }
2071
2072 int ooHandleTunneledH245Messages
2073    (OOH323CallData *call, H225H323_UU_PDU * pH323UUPdu)
2074 {
2075    H245Message *pmsg;
2076    OOCTXT *pctxt = call->msgctxt;
2077    int ret=0,i=0;
2078    
2079    OOTRACEDBGC3("Checking for tunneled H.245 messages (%s, %s)\n", 
2080                  call->callType, call->callToken);
2081
2082    /* Check whether there are tunneled messages */  
2083    if(pH323UUPdu->m.h245TunnelingPresent)
2084    {
2085       if(pH323UUPdu->h245Tunneling)
2086       {
2087          OOTRACEDBGB4("Total number of tunneled H245 messages are %d.(%s, %s)"
2088                       "\n", (int)pH323UUPdu->h245Control.n, call->callType, 
2089                       call->callToken);
2090          for(i=0; i< (int)pH323UUPdu->h245Control.n; i++)
2091          {
2092             OOTRACEDBGC5("Retrieving %d of %d tunneled H.245 messages."
2093                          "(%s, %s)\n",i+1, pH323UUPdu->h245Control.n,
2094                          call->callType, call->callToken);
2095             pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
2096             if(!pmsg)
2097             {
2098                OOTRACEERR3("Error:Memory - ooHandleH245TunneledMessages - pmsg"
2099                           "(%s, %s)\n", call->callType, call->callToken);
2100                return OO_FAILED;
2101             }
2102
2103             setPERBuffer(pctxt, 
2104                          (ASN1OCTET*)pH323UUPdu->h245Control.elem[i].data,
2105                          pH323UUPdu->h245Control.elem[i].numocts, 1);  
2106
2107             initializePrintHandler(&printHandler, "Tunneled H.245 Message");
2108             memset(pmsg, 0, sizeof(H245Message));
2109             /* Set event handler */
2110             setEventHandler (pctxt, &printHandler);
2111             OOTRACEDBGC4("Decoding %d tunneled H245 message. (%s, %s)\n", 
2112                           i+1, call->callType, call->callToken);
2113             ret = asn1PD_H245MultimediaSystemControlMessage(pctxt, 
2114                                                             &(pmsg->h245Msg));
2115             if(ret != ASN_OK)
2116             {
2117                OOTRACEERR3("Error decoding H245 message (%s, %s)\n", 
2118                             call->callType, call->callToken);
2119                ooFreeH245Message(call,pmsg);
2120                return OO_FAILED;
2121             }
2122             finishPrint();
2123             removeEventHandler (pctxt);
2124             ooHandleH245Message(call, pmsg);
2125             memFreePtr(pctxt, pmsg);
2126             pmsg = NULL;
2127          }/* End of For loop */
2128       }/* End of if(h245Tunneling) */
2129    }
2130    return OO_OK;
2131 }
2132
2133 int ooH323RetrieveAliases
2134    (OOH323CallData *call, H225_SeqOfH225AliasAddress *pAddresses, 
2135     OOAliases **aliasList)
2136 {
2137    int i=0,j=0,k=0;
2138    DListNode* pNode=NULL;
2139    H225AliasAddress *pAliasAddress=NULL;
2140    OOAliases *newAlias=NULL;
2141    H225TransportAddress *pTransportAddrss=NULL;
2142
2143    if(!pAddresses)
2144    {
2145       OOTRACEWARN3("Warn:No Aliases present (%s, %s)\n", call->callType, 
2146                     call->callToken);
2147       return OO_OK;
2148    }
2149    /* check for aliases */
2150    if(pAddresses->count<=0)
2151       return OO_OK;
2152    
2153    for(i=0; i<(int)pAddresses->count; i++)
2154    {
2155       pNode = dListFindByIndex (pAddresses, i);
2156
2157       if(!pNode)
2158          continue;
2159
2160       pAliasAddress = (H225AliasAddress*)pNode->data;
2161
2162       if(!pAliasAddress)
2163          continue;
2164
2165       newAlias = (OOAliases*)memAlloc(call->pctxt, sizeof(OOAliases));
2166       if(!newAlias)
2167       {
2168          OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - newAlias "
2169                      "(%s, %s)\n", call->callType, call->callToken);
2170          return OO_FAILED;
2171       }
2172       memset(newAlias, 0, sizeof(OOAliases));
2173       switch(pAliasAddress->t)
2174       {
2175       case T_H225AliasAddress_dialedDigits:
2176          newAlias->type = T_H225AliasAddress_dialedDigits;
2177          newAlias->value = (char*) memAlloc(call->pctxt, 
2178                          strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2179          if(!newAlias->value)
2180          {
2181             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2182                         "newAlias->value(dialedDigits) (%s, %s)\n", 
2183                          call->callType, call->callToken);
2184             memFreePtr(call->pctxt, newAlias);  
2185             return OO_FAILED;
2186          }
2187
2188          memcpy(newAlias->value, pAliasAddress->u.dialedDigits,
2189                            strlen(pAliasAddress->u.dialedDigits)*sizeof(char));
2190          newAlias->value[strlen(pAliasAddress->u.dialedDigits)*sizeof(char)]='\0';
2191          break;
2192       case T_H225AliasAddress_h323_ID:
2193          newAlias->type = T_H225AliasAddress_h323_ID;
2194          newAlias->value = (char*)memAlloc(call->pctxt, 
2195                          (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2196          if(!newAlias->value)
2197          {
2198             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2199                         "newAlias->value(h323id) (%s, %s)\n", call->callType, 
2200                          call->callToken);
2201             memFreePtr(call->pctxt, newAlias);  
2202             return OO_FAILED;
2203          }
2204
2205          for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2206          {
2207             if(pAliasAddress->u.h323_ID.data[j] < 256)
2208             {
2209                newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2210             }
2211          }
2212          newAlias->value[k] = '\0';
2213          break;   
2214       case T_H225AliasAddress_url_ID:
2215          newAlias->type = T_H225AliasAddress_url_ID;
2216          newAlias->value = (char*)memAlloc(call->pctxt,
2217                               strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2218          if(!newAlias->value)
2219          {
2220             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2221                         "newAlias->value(urlid) (%s, %s)\n", call->callType, 
2222                          call->callToken);
2223             memFreePtr(call->pctxt, newAlias);  
2224             return OO_FAILED;
2225          }
2226
2227          memcpy(newAlias->value, pAliasAddress->u.url_ID,
2228                                strlen(pAliasAddress->u.url_ID)*sizeof(char));
2229          newAlias->value[strlen(pAliasAddress->u.url_ID)*sizeof(char)]='\0';
2230          break;
2231       case T_H225AliasAddress_transportID:
2232         newAlias->type = T_H225AliasAddress_transportID;
2233         pTransportAddrss = pAliasAddress->u.transportID;
2234         if(pTransportAddrss->t == T_H225TransportAddress_ip6Address) {
2235          /* hopefully ip:port value can't exceed more than 30 
2236             characters */
2237          newAlias->value = (char*)memAlloc(call->pctxt, 
2238                                                       INET6_ADDRSTRLEN*sizeof(char)*2);
2239          inet_ntop(AF_INET6, pTransportAddrss->u.ip6Address->ip.data, newAlias->value, INET6_ADDRSTRLEN);
2240          sprintf(newAlias->value+strlen(newAlias->value), ":%d", pTransportAddrss->u.ip6Address->port);
2241         } else if(pTransportAddrss->t == T_H225TransportAddress_ipAddress) {
2242          /* hopefully ip:port value can't exceed more than 30 
2243             characters */
2244          newAlias->value = (char*)memAlloc(call->pctxt, 
2245                                                       30*sizeof(char));
2246          sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2247                                   pTransportAddrss->u.ipAddress->ip.data[0],
2248                                   pTransportAddrss->u.ipAddress->ip.data[1],
2249                                   pTransportAddrss->u.ipAddress->ip.data[2],
2250                                   pTransportAddrss->u.ipAddress->ip.data[3],
2251                                   pTransportAddrss->u.ipAddress->port);
2252         } else {
2253          OOTRACEERR3("Error:Alias transportID not an IP4 nor IP6 address"
2254                      "(%s, %s)\n", call->callType, call->callToken);
2255          memFreePtr(call->pctxt, newAlias);
2256         }
2257         break;
2258       case T_H225AliasAddress_email_ID:
2259          newAlias->type = T_H225AliasAddress_email_ID;
2260          newAlias->value = (char*)memAlloc(call->pctxt, 
2261                              strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2262          if(!newAlias->value)
2263          {
2264             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2265                         "newAlias->value(emailid) (%s, %s)\n", call->callType, 
2266                          call->callToken);
2267             memFreePtr(call->pctxt, newAlias);  
2268             return OO_FAILED;
2269          }
2270
2271          memcpy(newAlias->value, pAliasAddress->u.email_ID,
2272                               strlen(pAliasAddress->u.email_ID)*sizeof(char));
2273          newAlias->value[strlen(pAliasAddress->u.email_ID)*sizeof(char)]='\0';
2274          break;
2275       default:
2276          OOTRACEERR3("Error:Unhandled Alias type (%s, %s)\n", 
2277                        call->callType, call->callToken);
2278          memFreePtr(call->pctxt, newAlias);
2279          continue;
2280       }
2281
2282       newAlias->next = *aliasList;
2283       *aliasList = newAlias;
2284
2285       newAlias = NULL;
2286      
2287      pAliasAddress = NULL;
2288      pNode = NULL;
2289    }/* endof: for */
2290    return OO_OK;
2291 }
2292
2293
2294 int ooPopulatePrefixList(OOCTXT *pctxt, OOAliases *pAliases,
2295                            H225_SeqOfH225SupportedPrefix *pPrefixList )
2296 {
2297    H225SupportedPrefix *pPrefixEntry=NULL;
2298    OOAliases * pAlias=NULL;
2299    ASN1BOOL bValid=FALSE;
2300
2301    dListInit(pPrefixList);
2302    if(pAliases)
2303    {
2304       pAlias = pAliases;
2305       while(pAlias)
2306       {
2307          pPrefixEntry = NULL;
2308          switch(pAlias->type)
2309          {
2310          case T_H225AliasAddress_dialedDigits:
2311             pPrefixEntry = (H225SupportedPrefix *)memAlloc(pctxt, 
2312                                                      sizeof(H225SupportedPrefix));
2313             if(!pPrefixEntry) {
2314                 OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - pAliasEntry\n");
2315                 return OO_FAILED;
2316             }
2317             pPrefixEntry->prefix.t = T_H225AliasAddress_dialedDigits;
2318             pPrefixEntry->prefix.u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2319                                                      strlen(pAlias->value)+1);
2320             if(!pPrefixEntry->prefix.u.dialedDigits) {
2321                OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - "
2322                            "dialedDigits\n");
2323                memFreePtr(pctxt, pPrefixEntry);
2324                return OO_FAILED;
2325             }
2326             strcpy(*(char**)&pPrefixEntry->prefix.u.dialedDigits, pAlias->value);
2327             bValid = TRUE;
2328             break;
2329          default:
2330             bValid = FALSE;                  
2331          }
2332          
2333          if(bValid)
2334             dListAppend( pctxt, pPrefixList, (void*)pPrefixEntry );
2335          
2336          pAlias = pAlias->next;
2337       }
2338    }
2339    return OO_OK;
2340 }
2341 int ooPopulateAliasList(OOCTXT *pctxt, OOAliases *pAliases,
2342                            H225_SeqOfH225AliasAddress *pAliasList, int pAliasType)
2343 {
2344    H225AliasAddress *pAliasEntry=NULL;
2345    OOAliases * pAlias=NULL;
2346    ASN1BOOL bValid=FALSE;
2347    int i = 0;
2348
2349    dListInit(pAliasList);
2350    if(pAliases)
2351    {
2352       pAlias = pAliases;
2353       while(pAlias)
2354       {
2355          if (pAlias->value[0] == 0) {
2356           pAlias = pAlias->next;
2357           continue;
2358          }
2359          pAliasEntry = (H225AliasAddress*)memAlloc(pctxt, 
2360                                                      sizeof(H225AliasAddress));
2361          if(!pAliasEntry)
2362          {
2363             OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - pAliasEntry\n");
2364             return OO_FAILED;
2365          }
2366
2367          if (pAliasType && pAlias->type != pAliasType) {
2368                 pAlias = pAlias->next;
2369                 continue;
2370          }
2371          switch(pAlias->type)
2372          {
2373             case T_H225AliasAddress_dialedDigits:
2374              pAliasEntry->t = T_H225AliasAddress_dialedDigits;
2375              pAliasEntry->u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2376                                                      strlen(pAlias->value)+1);
2377              if(!pAliasEntry->u.dialedDigits)
2378              {
2379                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - "
2380                            "dialedDigits\n");
2381                memFreePtr(pctxt, pAliasEntry);
2382                return OO_FAILED;
2383              }
2384              strcpy(*(char**)&pAliasEntry->u.dialedDigits, pAlias->value);
2385              bValid = TRUE;
2386             break;
2387          case T_H225AliasAddress_h323_ID:
2388             pAliasEntry->t = T_H225AliasAddress_h323_ID;
2389             pAliasEntry->u.h323_ID.nchars = strlen(pAlias->value);
2390             pAliasEntry->u.h323_ID.data = (ASN116BITCHAR*)memAllocZ
2391                      (pctxt, strlen(pAlias->value)*sizeof(ASN116BITCHAR));
2392             
2393             if(!pAliasEntry->u.h323_ID.data)
2394             {
2395                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - h323_id\n");
2396                memFreePtr(pctxt, pAliasEntry);
2397                return OO_FAILED;
2398             }
2399             for(i=0; *(pAlias->value+i) != '\0'; i++)
2400                pAliasEntry->u.h323_ID.data[i] =(ASN116BITCHAR)pAlias->value[i];
2401             bValid = TRUE;
2402             break;
2403          case T_H225AliasAddress_url_ID:
2404             pAliasEntry->t = T_H225AliasAddress_url_ID;
2405             pAliasEntry->u.url_ID = (ASN1IA5String)memAlloc(pctxt, 
2406                                                      strlen(pAlias->value)+1);
2407             if(!pAliasEntry->u.url_ID)
2408             {
2409                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - url_id\n");
2410                memFreePtr(pctxt, pAliasEntry);               
2411                return OO_FAILED;
2412             }
2413             strcpy(*(char**)&pAliasEntry->u.url_ID, pAlias->value);
2414             bValid = TRUE;
2415             break;
2416          case T_H225AliasAddress_email_ID:
2417             pAliasEntry->t = T_H225AliasAddress_email_ID;
2418             pAliasEntry->u.email_ID = (ASN1IA5String)memAlloc(pctxt, 
2419                                                      strlen(pAlias->value)+1);
2420             if(!pAliasEntry->u.email_ID)
2421             {
2422                OOTRACEERR1("ERROR: Failed to allocate memory for EmailID "
2423                            "alias entry \n");
2424                return OO_FAILED;
2425             }
2426             strcpy(*(char**)&pAliasEntry->u.email_ID, pAlias->value);
2427             bValid = TRUE;
2428             break;
2429          default:
2430             OOTRACEERR1("ERROR: Unhandled alias type\n");
2431             bValid = FALSE;                  
2432          }
2433          
2434          if(bValid)
2435             dListAppend( pctxt, pAliasList, (void*)pAliasEntry );
2436          else
2437             memFreePtr(pctxt, pAliasEntry);
2438          
2439          pAlias = pAlias->next;
2440       }
2441    }
2442    return OO_OK;
2443 }
2444
2445
2446 OOAliases* ooH323GetAliasFromList(OOAliases *aliasList, int type, char *value)
2447 {
2448
2449    OOAliases *pAlias = NULL;
2450
2451    if(!aliasList)
2452    {
2453       OOTRACEDBGC1("No alias List to search\n");
2454       return NULL;
2455    }
2456
2457    pAlias = aliasList;
2458
2459    while(pAlias)
2460    {
2461      if(type != 0 && value) { /* Search by type and value */
2462          if(pAlias->type == type && !strcmp(pAlias->value, value))
2463          {
2464             return pAlias;
2465          }
2466       }
2467       else if(type != 0 && !value) {/* search by type */
2468          if(pAlias->type == type)
2469             return pAlias;
2470       }
2471       else if(type == 0 && value) {/* search by value */
2472          if(!strcmp(pAlias->value, value))
2473             return pAlias;
2474       }
2475       else {
2476          OOTRACEDBGC1("No criteria to search the alias list\n");
2477          return NULL;
2478       }
2479       pAlias = pAlias->next;
2480    }
2481
2482    return NULL;
2483 }
2484
2485 OOAliases* ooH323AddAliasToList
2486 (OOAliases **pAliasList, OOCTXT *pctxt, H225AliasAddress *pAliasAddress)
2487 {
2488    int j=0,k=0;
2489    OOAliases *newAlias=NULL;
2490    H225TransportAddress *pTransportAddrss=NULL;
2491    
2492    newAlias = (OOAliases*) memAlloc(pctxt, sizeof(OOAliases));
2493    if(!newAlias)
2494    {
2495       OOTRACEERR1("Error: Failed to allocate memory for new alias to be added to the alias list\n");
2496       return NULL;
2497    }
2498    memset(newAlias, 0, sizeof(OOAliases));
2499
2500    switch(pAliasAddress->t)
2501    {
2502    case T_H225AliasAddress_dialedDigits:
2503       newAlias->type = T_H225AliasAddress_dialedDigits;
2504       newAlias->value = (char*) memAlloc(pctxt, strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2505       strcpy(newAlias->value, pAliasAddress->u.dialedDigits);
2506       break;
2507    case T_H225AliasAddress_h323_ID:
2508       newAlias->type = T_H225AliasAddress_h323_ID;
2509       newAlias->value = (char*)memAlloc(pctxt, 
2510                            (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2511
2512       for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2513       {
2514          if(pAliasAddress->u.h323_ID.data[j] < 256)
2515          {
2516             newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2517          }
2518       }
2519       newAlias->value[k] = '\0';
2520       break;   
2521    case T_H225AliasAddress_url_ID:
2522       newAlias->type = T_H225AliasAddress_url_ID;
2523       newAlias->value = (char*)memAlloc(pctxt,
2524                             strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2525
2526       strcpy(newAlias->value, pAliasAddress->u.url_ID);
2527       break;
2528    case T_H225AliasAddress_transportID:
2529       newAlias->type = T_H225AliasAddress_transportID;
2530       pTransportAddrss = pAliasAddress->u.transportID;
2531       if(pTransportAddrss->t == T_H225TransportAddress_ip6Address) {
2532        /* hopefully ip:port value can't exceed more than 30 
2533          characters */
2534        newAlias->value = (char*)memAlloc(pctxt, 
2535                                               INET6_ADDRSTRLEN*sizeof(char)*2);
2536        inet_ntop(AF_INET6, pTransportAddrss->u.ip6Address->ip.data, newAlias->value, INET6_ADDRSTRLEN);
2537        sprintf(newAlias->value+strlen(newAlias->value), ":%d", pTransportAddrss->u.ip6Address->port);
2538       } else if(pTransportAddrss->t == T_H225TransportAddress_ipAddress) {
2539        /* hopefully ip:port value can't exceed more than 30 
2540          characters */
2541        newAlias->value = (char*)memAlloc(pctxt, 
2542                                               30*sizeof(char));
2543        sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2544                                pTransportAddrss->u.ipAddress->ip.data[0],
2545                                pTransportAddrss->u.ipAddress->ip.data[1],
2546                                pTransportAddrss->u.ipAddress->ip.data[2],
2547                                pTransportAddrss->u.ipAddress->ip.data[3],
2548                                pTransportAddrss->u.ipAddress->port);
2549       } else {
2550        OOTRACEERR1("Error:Alias transportID not an IP4 nor IP6 address\n");
2551        memFreePtr(pctxt, newAlias);
2552        return NULL;
2553       }
2554       break;
2555    case T_H225AliasAddress_email_ID:
2556       newAlias->type = T_H225AliasAddress_email_ID;
2557       newAlias->value = (char*)memAlloc(pctxt, 
2558                  strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2559
2560       strcpy(newAlias->value, pAliasAddress->u.email_ID);
2561       break;
2562    default:
2563       OOTRACEERR1("Error:Unhandled Alias type \n");
2564       memFreePtr(pctxt, newAlias);
2565       return NULL;
2566
2567    }
2568    newAlias->next = *pAliasList;
2569    *pAliasList= newAlias;
2570    return newAlias;
2571 }
2572
2573 int ooH323GetIpPortFromH225TransportAddress(struct OOH323CallData *call, 
2574    H225TransportAddress *h225Address, char *ip, int *port)
2575 {
2576    if (call->versionIP == 6) {
2577     if(h225Address->t != T_H225TransportAddress_ip6Address)
2578     {
2579       OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
2580                    call->callToken);
2581       return OO_FAILED;
2582     }
2583     inet_ntop(AF_INET6, h225Address->u.ip6Address->ip.data, ip, INET6_ADDRSTRLEN);
2584     *port = h225Address->u.ip6Address->port;
2585     return OO_OK;
2586    }
2587    if(h225Address->t != T_H225TransportAddress_ipAddress)
2588    {
2589       OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
2590                    call->callToken);
2591       return OO_FAILED;
2592    }
2593    sprintf(ip, "%d.%d.%d.%d", 
2594               h225Address->u.ipAddress->ip.data[0], 
2595               h225Address->u.ipAddress->ip.data[1],
2596               h225Address->u.ipAddress->ip.data[2],
2597               h225Address->u.ipAddress->ip.data[3]);
2598    *port = h225Address->u.ipAddress->port;
2599    return OO_OK;
2600 }