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