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