6cd3d881260a4f304334452a37eb0afd5d9d876d
[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    }
786    return OO_OK;
787 }
788
789
790 int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
791 {
792    H225Alerting_UUIE *alerting=NULL;
793    H245OpenLogicalChannel* olc;
794    ASN1OCTET msgbuf[MAXMSGLEN];
795    ooLogicalChannel * pChannel = NULL;
796    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
797    int i=0, ret=0;
798
799
800    if(!q931Msg->userInfo)
801    {
802       OOTRACEERR3("ERROR:No User-User IE in received Alerting message."
803                   " (%s, %s)\n", call->callType, call->callToken);
804       return OO_FAILED;
805    }
806    alerting = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.alerting;
807    if(alerting == NULL)
808    {
809       OOTRACEERR3("Error: Received Alerting message does not have "
810                   "alerting UUIE (%s, %s)\n", call->callType, 
811                   call->callToken);
812       /* Mark call for clearing */
813       if(call->callState < OO_CALL_CLEAR)
814       {
815          call->callEndReason = OO_REASON_INVALIDMESSAGE;
816          call->callState = OO_CALL_CLEAR;
817       }
818       return OO_FAILED;
819    }
820    /*Handle fast-start */
821    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
822       !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
823    {
824       if(alerting->m.fastStartPresent)
825       {
826          /* For printing the decoded message to log, initialize handler. */
827          initializePrintHandler(&printHandler, "FastStart Elements");
828
829          /* Set print handler */
830          setEventHandler (call->pctxt, &printHandler);
831
832          for(i=0; i<(int)alerting->fastStart.n; i++)
833          {
834             olc = NULL;
835
836             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
837                                               sizeof(H245OpenLogicalChannel));
838             if(!olc)
839             {
840                OOTRACEERR3("ERROR:Memory - ooOnReceivedAlerting - olc"
841                            "(%s, %s)\n", call->callType, call->callToken);
842                /*Mark call for clearing */
843                if(call->callState < OO_CALL_CLEAR)
844                {
845                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
846                   call->callState = OO_CALL_CLEAR;
847                }
848                return OO_FAILED;
849             }
850             memset(olc, 0, sizeof(H245OpenLogicalChannel));
851             memcpy(msgbuf, alerting->fastStart.elem[i].data, 
852                                     alerting->fastStart.elem[i].numocts);
853             setPERBuffer(call->pctxt, msgbuf, 
854                          alerting->fastStart.elem[i].numocts, 1);
855             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
856             if(ret != ASN_OK)
857             {
858                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
859                            "(%s, %s)\n", call->callType, call->callToken);
860                /* Mark call for clearing */
861                if(call->callState < OO_CALL_CLEAR)
862                {
863                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
864                   call->callState = OO_CALL_CLEAR;
865                }
866                return OO_FAILED;
867             }
868
869             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
870
871             pChannel = ooFindLogicalChannelByOLC(call, olc);
872             if(!pChannel)
873             {
874                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
875                            "(%s, %s)\n",
876                             olc->forwardLogicalChannelNumber, call->callType, 
877                             call->callToken);
878                return OO_FAILED;
879             }
880             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
881             {
882                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
883                             "Number from %d to %d (%s, %s)\n", 
884                             pChannel->channelNo, 
885                             olc->forwardLogicalChannelNumber, call->callType, 
886                             call->callToken);
887                pChannel->channelNo = olc->forwardLogicalChannelNumber;
888             }
889             if(!strcmp(pChannel->dir, "transmit"))
890             {
891                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
892                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
893                {
894                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
895                               "channel %d (%s, %s)\n", 
896                               olc->forwardLogicalChannelNumber, call->callType,
897                               call->callToken);
898                   continue;
899                }
900             
901                /* Extract the remote media endpoint address */
902                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
903                if(!h2250lcp)
904                {
905                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
906                               "forward Logical Channel Parameters found. "
907                               "(%s, %s)\n", call->callType, call->callToken);
908                   return OO_FAILED;
909                }
910                if(!h2250lcp->m.mediaChannelPresent)
911                {
912                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
913                               "reverse media channel information found."
914                               "(%s, %s)\n", call->callType, call->callToken);
915                   return OO_FAILED;
916                }
917                ret = ooGetIpPortFromH245TransportAddress(call, 
918                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
919                                    &pChannel->remoteMediaPort);
920                
921                if(ret != OO_OK)
922                {
923                 if(call->callState < OO_CALL_CLEAR)
924                 {
925                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
926                   call->callState = OO_CALL_CLEAR;
927                 }
928                   OOTRACEERR3("ERROR:Unsupported media channel address type "
929                               "(%s, %s)\n", call->callType, call->callToken);
930                   return OO_FAILED;
931                }
932        
933                if(!pChannel->chanCap->startTransmitChannel)
934                {
935                   OOTRACEERR3("ERROR:No callback registered to start transmit "
936                               "channel (%s, %s)\n",call->callType, 
937                               call->callToken);
938                   return OO_FAILED;
939                }
940                pChannel->chanCap->startTransmitChannel(call, pChannel);
941                /* Mark the current channel as established and close all other 
942                   logical channels with same session id and in same direction.
943                */
944                ooOnLogicalChannelEstablished(call, pChannel);
945             }
946          }
947          finishPrint();
948          removeEventHandler(call->pctxt);
949          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
950       } 
951
952    }
953
954    /* Retrieve the H.245 control channel address from the connect msg */
955    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
956       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
957       alerting->m.h245AddressPresent) {
958       OOTRACEINFO3("Tunneling and h245address provided."
959                    "Giving preference to Tunneling (%s, %s)\n", 
960                    call->callType, call->callToken);
961    }
962    else if(alerting->m.h245AddressPresent)
963    {
964       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
965       {
966          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
967          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
968                       "provided in Alerting message (%s, %s)\n", 
969                       call->callType, call->callToken);
970       }
971       ret = ooH323GetIpPortFromH225TransportAddress(call, 
972                                   &alerting->h245Address, call->remoteIP,
973                                   &call->remoteH245Port);
974       if(ret != OO_OK)
975       {
976          OOTRACEERR3("Error: Unknown H245 address type in received "
977                      "Alerting message (%s, %s)", call->callType, 
978                      call->callToken);
979          /* Mark call for clearing */
980          if(call->callState < OO_CALL_CLEAR)
981          {
982             call->callEndReason = OO_REASON_INVALIDMESSAGE;
983             call->callState = OO_CALL_CLEAR;
984          }
985          return OO_FAILED;
986       }
987       if(call->remoteH245Port != 0 && !call->pH245Channel) {
988       /* Create an H.245 connection. 
989       */
990        if(ooCreateH245Connection(call)== OO_FAILED)
991        {
992          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
993                      call->callType, call->callToken);
994
995          if(call->callState < OO_CALL_CLEAR)
996          {
997             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
998             call->callState = OO_CALL_CLEAR;
999          }
1000          return OO_FAILED;
1001        }
1002       }
1003    } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1004         ret =ooSendTCSandMSD(call);
1005         if (ret != OO_OK)
1006                 return ret;
1007    }
1008
1009
1010    return OO_OK;
1011 }
1012
1013 int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
1014 {
1015    H225Progress_UUIE *progress=NULL;
1016    H245OpenLogicalChannel* olc;
1017    ASN1OCTET msgbuf[MAXMSGLEN];
1018    ooLogicalChannel * pChannel = NULL;
1019    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
1020    int i=0, ret=0;
1021
1022
1023    if(!q931Msg->userInfo)
1024    {
1025       OOTRACEERR3("ERROR:No User-User IE in received Progress message."
1026                   " (%s, %s)\n", call->callType, call->callToken);
1027       return OO_FAILED;
1028    }
1029    progress = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.progress;
1030    if(progress == NULL)
1031    {
1032       OOTRACEERR3("Error: Received Progress message does not have "
1033                   "progress UUIE (%s, %s)\n", call->callType, 
1034                   call->callToken);
1035       /* Mark call for clearing */
1036       if(call->callState < OO_CALL_CLEAR)
1037       {
1038          call->callEndReason = OO_REASON_INVALIDMESSAGE;
1039          call->callState = OO_CALL_CLEAR;
1040       }
1041       return OO_FAILED;
1042    }
1043    /*Handle fast-start */
1044    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
1045       !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
1046    {
1047       if(progress->m.fastStartPresent)
1048       {
1049          /* For printing the decoded message to log, initialize handler. */
1050          initializePrintHandler(&printHandler, "FastStart Elements");
1051
1052          /* Set print handler */
1053          setEventHandler (call->pctxt, &printHandler);
1054
1055          for(i=0; i<(int)progress->fastStart.n; i++)
1056          {
1057             olc = NULL;
1058
1059             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
1060                                               sizeof(H245OpenLogicalChannel));
1061             if(!olc)
1062             {
1063                OOTRACEERR3("ERROR:Memory - ooOnReceivedProgress - olc"
1064                            "(%s, %s)\n", call->callType, call->callToken);
1065                /*Mark call for clearing */
1066                if(call->callState < OO_CALL_CLEAR)
1067                {
1068                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
1069                   call->callState = OO_CALL_CLEAR;
1070                }
1071                return OO_FAILED;
1072             }
1073             memset(olc, 0, sizeof(H245OpenLogicalChannel));
1074             memcpy(msgbuf, progress->fastStart.elem[i].data, 
1075                                     progress->fastStart.elem[i].numocts);
1076             setPERBuffer(call->pctxt, msgbuf, 
1077                          progress->fastStart.elem[i].numocts, 1);
1078             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
1079             if(ret != ASN_OK)
1080             {
1081                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
1082                            "(%s, %s)\n", call->callType, call->callToken);
1083                /* Mark call for clearing */
1084                if(call->callState < OO_CALL_CLEAR)
1085                {
1086                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
1087                   call->callState = OO_CALL_CLEAR;
1088                }
1089                return OO_FAILED;
1090             }
1091
1092             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
1093
1094             pChannel = ooFindLogicalChannelByOLC(call, olc);
1095             if(!pChannel)
1096             {
1097                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
1098                            "(%s, %s)\n",
1099                             olc->forwardLogicalChannelNumber, call->callType, 
1100                             call->callToken);
1101                return OO_FAILED;
1102             }
1103             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
1104             {
1105                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
1106                             "Number from %d to %d (%s, %s)\n", 
1107                             pChannel->channelNo, 
1108                             olc->forwardLogicalChannelNumber, call->callType, 
1109                             call->callToken);
1110                pChannel->channelNo = olc->forwardLogicalChannelNumber;
1111             }
1112             if(!strcmp(pChannel->dir, "transmit"))
1113             {
1114                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
1115                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
1116                {
1117                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
1118                               "channel %d (%s, %s)\n", 
1119                               olc->forwardLogicalChannelNumber, call->callType,
1120                               call->callToken);
1121                   continue;
1122                }
1123             
1124                /* Extract the remote media endpoint address */
1125                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
1126                if(!h2250lcp)
1127                {
1128                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1129                               "forward Logical Channel Parameters found. "
1130                               "(%s, %s)\n", call->callType, call->callToken);
1131                   return OO_FAILED;
1132                }
1133                if(!h2250lcp->m.mediaChannelPresent)
1134                {
1135                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1136                               "reverse media channel information found."
1137                               "(%s, %s)\n", call->callType, call->callToken);
1138                   return OO_FAILED;
1139                }
1140                ret = ooGetIpPortFromH245TransportAddress(call, 
1141                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
1142                                    &pChannel->remoteMediaPort);
1143                
1144                if(ret != OO_OK)
1145                {
1146                 if(call->callState < OO_CALL_CLEAR)
1147                 {
1148                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
1149                   call->callState = OO_CALL_CLEAR;
1150                 }
1151                   OOTRACEERR3("ERROR:Unsupported media channel address type "
1152                               "(%s, %s)\n", call->callType, call->callToken);
1153                   return OO_FAILED;
1154                }
1155        
1156                if(!pChannel->chanCap->startTransmitChannel)
1157                {
1158                   OOTRACEERR3("ERROR:No callback registered to start transmit "
1159                               "channel (%s, %s)\n",call->callType, 
1160                               call->callToken);
1161                   return OO_FAILED;
1162                }
1163                pChannel->chanCap->startTransmitChannel(call, pChannel);
1164             }
1165             /* Mark the current channel as established and close all other 
1166                logical channels with same session id and in same direction.
1167             */
1168             ooOnLogicalChannelEstablished(call, pChannel);
1169          }
1170          finishPrint();
1171          removeEventHandler(call->pctxt);
1172          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
1173       }
1174       
1175    }
1176
1177    /* Retrieve the H.245 control channel address from the connect msg */
1178    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
1179       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
1180       progress->m.h245AddressPresent) {
1181       OOTRACEINFO3("Tunneling and h245address provided."
1182                    "Giving preference to Tunneling (%s, %s)\n", 
1183                    call->callType, call->callToken);
1184    }
1185    else if(progress->m.h245AddressPresent)
1186    {
1187       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1188       {
1189          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1190          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
1191                       "provided in Progress message (%s, %s)\n", 
1192                       call->callType, call->callToken);
1193       }
1194       ret = ooH323GetIpPortFromH225TransportAddress(call, 
1195                                   &progress->h245Address, call->remoteIP,
1196                                   &call->remoteH245Port);
1197       if(ret != OO_OK)
1198       {
1199          OOTRACEERR3("Error: Unknown H245 address type in received "
1200                      "Progress message (%s, %s)", call->callType, 
1201                      call->callToken);
1202          /* Mark call for clearing */
1203          if(call->callState < OO_CALL_CLEAR)
1204          {
1205             call->callEndReason = OO_REASON_INVALIDMESSAGE;
1206             call->callState = OO_CALL_CLEAR;
1207          }
1208          return OO_FAILED;
1209       }
1210       if(call->remoteH245Port != 0 && !call->pH245Channel) {
1211        /* Create an H.245 connection. 
1212       */
1213        if(ooCreateH245Connection(call)== OO_FAILED)
1214        {
1215          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
1216                      call->callType, call->callToken);
1217
1218          if(call->callState < OO_CALL_CLEAR)
1219          {
1220             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1221             call->callState = OO_CALL_CLEAR;
1222          }
1223          return OO_FAILED;
1224        }
1225       }
1226    } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) {
1227         ret =ooSendTCSandMSD(call);
1228         if (ret != OO_OK)
1229                 return ret;
1230    }
1231
1232    return OO_OK;
1233 }
1234    
1235
1236 int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
1237 {
1238    int ret, i;
1239    H225Connect_UUIE *connect;
1240    H245OpenLogicalChannel* olc;
1241    ASN1OCTET msgbuf[MAXMSGLEN];
1242    ooLogicalChannel * pChannel = NULL;
1243    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
1244
1245    if(!q931Msg->userInfo)
1246    {
1247       OOTRACEERR3("Error: UUIE not found in received H.225 Connect message"
1248                   " (%s, %s)\n", call->callType, call->callToken);
1249       /* Mark call for clearing */
1250       if(call->callState < OO_CALL_CLEAR)
1251       {
1252          call->callEndReason = OO_REASON_INVALIDMESSAGE;
1253          call->callState = OO_CALL_CLEAR;
1254       }
1255       return OO_FAILED;
1256    }
1257    /* Retrieve the connect message from the user-user IE & Q.931 header */
1258    connect = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.connect;
1259    if(connect == NULL)
1260    {
1261       OOTRACEERR3("Error: Received Connect message does not have Connect UUIE"
1262                   " (%s, %s)\n", call->callType, call->callToken);
1263       /* Mark call for clearing */
1264       if(call->callState < OO_CALL_CLEAR)
1265       {
1266          call->callEndReason = OO_REASON_INVALIDMESSAGE;
1267          call->callState = OO_CALL_CLEAR;
1268       }
1269       return OO_FAILED;
1270    }
1271
1272    /*Handle fast-start */
1273    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) && 
1274       !OO_TESTFLAG (call->flags, OO_M_FASTSTARTANSWERED))
1275    {
1276       if(!connect->m.fastStartPresent)
1277       {
1278          OOTRACEINFO3("Remote endpoint has rejected fastStart. (%s, %s)\n",
1279                       call->callType, call->callToken);
1280          /* Clear all channels we might have created */
1281          ooClearAllLogicalChannels(call);
1282          OO_CLRFLAG (call->flags, OO_M_FASTSTART);
1283       }
1284    }
1285
1286    if (connect->m.fastStartPresent && 
1287        !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
1288    {
1289       /* For printing the decoded message to log, initialize handler. */
1290       initializePrintHandler(&printHandler, "FastStart Elements");
1291
1292       /* Set print handler */
1293       setEventHandler (call->pctxt, &printHandler);
1294
1295       for(i=0; i<(int)connect->fastStart.n; i++)
1296       {
1297          olc = NULL;
1298          /* memset(msgbuf, 0, sizeof(msgbuf));*/
1299          olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
1300                                               sizeof(H245OpenLogicalChannel));
1301          if(!olc)
1302          {
1303             OOTRACEERR3("ERROR:Memory - ooOnReceivedSignalConnect - olc"
1304                         "(%s, %s)\n", call->callType, call->callToken);
1305             /*Mark call for clearing */
1306             if(call->callState < OO_CALL_CLEAR)
1307             {
1308                call->callEndReason = OO_REASON_LOCAL_CLEARED;
1309                call->callState = OO_CALL_CLEAR;
1310             }
1311             finishPrint();
1312             removeEventHandler(call->pctxt);
1313             return OO_FAILED;
1314          }
1315          memset(olc, 0, sizeof(H245OpenLogicalChannel));
1316          memcpy(msgbuf, connect->fastStart.elem[i].data, 
1317                                            connect->fastStart.elem[i].numocts);
1318          setPERBuffer(call->pctxt, msgbuf, 
1319                       connect->fastStart.elem[i].numocts, 1);
1320          ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
1321          if(ret != ASN_OK)
1322          {
1323             OOTRACEERR3("ERROR:Failed to decode fast start olc element "
1324                         "(%s, %s)\n", call->callType, call->callToken);
1325             /* Mark call for clearing */
1326             if(call->callState < OO_CALL_CLEAR)
1327             {
1328                call->callEndReason = OO_REASON_INVALIDMESSAGE;
1329                call->callState = OO_CALL_CLEAR;
1330             }
1331             finishPrint();
1332             removeEventHandler(call->pctxt);
1333             return OO_FAILED;
1334          }
1335
1336          dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
1337
1338          pChannel = ooFindLogicalChannelByOLC(call, olc);
1339          if(!pChannel)
1340          {
1341             OOTRACEERR4("ERROR: Logical Channel %d not found, fasts start "
1342                         "answered. (%s, %s)\n",
1343                          olc->forwardLogicalChannelNumber, call->callType, 
1344                          call->callToken);
1345             finishPrint();
1346             removeEventHandler(call->pctxt);
1347             return OO_FAILED;
1348          }
1349          if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
1350          {
1351             OOTRACEINFO5("Remote endpoint changed forwardLogicalChannelNumber"
1352                          "from %d to %d (%s, %s)\n", pChannel->channelNo,
1353                           olc->forwardLogicalChannelNumber, call->callType, 
1354                           call->callToken);
1355             pChannel->channelNo = olc->forwardLogicalChannelNumber;
1356          }
1357          if(!strcmp(pChannel->dir, "transmit"))
1358          {
1359             if(olc->forwardLogicalChannelParameters.multiplexParameters.t != 
1360                T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
1361             {
1362                OOTRACEERR4("ERROR:Unknown multiplex parameter type for channel"
1363                            " %d (%s, %s)\n", olc->forwardLogicalChannelNumber, 
1364                            call->callType, call->callToken);
1365                continue;
1366             }
1367             
1368             /* Extract the remote media endpoint address */
1369             h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
1370             if(!h2250lcp)
1371             {
1372                OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1373                            "forward Logical Channel Parameters found. (%s, %s)"
1374                            "\n", call->callType, call->callToken);
1375                finishPrint();
1376                removeEventHandler(call->pctxt);
1377                return OO_FAILED;
1378             }
1379             if(!h2250lcp->m.mediaChannelPresent)
1380             {
1381                OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
1382                            "reverse media channel information found. (%s, %s)"
1383                            "\n", call->callType, call->callToken);
1384                finishPrint();
1385                removeEventHandler(call->pctxt);
1386                return OO_FAILED;
1387             }
1388
1389             ret = ooGetIpPortFromH245TransportAddress(call, 
1390                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
1391                                    &pChannel->remoteMediaPort);
1392             if(ret != OO_OK)
1393             {
1394                 if(call->callState < OO_CALL_CLEAR)
1395                 {
1396                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
1397                   call->callState = OO_CALL_CLEAR;
1398                 }
1399                OOTRACEERR3("ERROR:Unsupported media channel address type "
1400                            "(%s, %s)\n", call->callType, call->callToken);
1401                finishPrint();
1402                removeEventHandler(call->pctxt);
1403                return OO_FAILED;
1404             }
1405             if(!pChannel->chanCap->startTransmitChannel)
1406             {
1407                OOTRACEERR3("ERROR:No callback registered to start transmit "
1408                          "channel (%s, %s)\n",call->callType, call->callToken);
1409                finishPrint();
1410                removeEventHandler(call->pctxt);
1411                return OO_FAILED;
1412             }
1413             pChannel->chanCap->startTransmitChannel(call, pChannel);
1414          }
1415          /* Mark the current channel as established and close all other 
1416             logical channels with same session id and in same direction.
1417          */
1418          ooOnLogicalChannelEstablished(call, pChannel);
1419       }
1420       finishPrint();
1421       removeEventHandler(call->pctxt);
1422       OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
1423    }
1424
1425    /* Retrieve the H.245 control channel address from the CONNECT msg */
1426    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
1427       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
1428       connect->m.h245AddressPresent) {
1429       OOTRACEINFO3("Tunneling and h245address provided."
1430                    "Giving preference to Tunneling (%s, %s)\n", 
1431                    call->callType, call->callToken);
1432    }
1433    else if(connect->m.h245AddressPresent)
1434    {
1435       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1436       {
1437          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1438          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
1439                       "provided in connect message (%s, %s)\n", 
1440                       call->callType, call->callToken);
1441       }
1442       ret = ooH323GetIpPortFromH225TransportAddress(call, 
1443                  &connect->h245Address, call->remoteIP, &call->remoteH245Port);
1444       if(ret != OO_OK)
1445       {
1446          OOTRACEERR3("Error: Unknown H245 address type in received Connect "
1447                      "message (%s, %s)", call->callType, call->callToken);
1448          /* Mark call for clearing */
1449          if(call->callState < OO_CALL_CLEAR)
1450          {
1451             call->callEndReason = OO_REASON_INVALIDMESSAGE;
1452             call->callState = OO_CALL_CLEAR;
1453          }
1454          return OO_FAILED;
1455       }
1456    }
1457
1458    if(call->remoteH245Port != 0 && !call->pH245Channel)
1459    {
1460        /* Create an H.245 connection. 
1461       */
1462       if(ooCreateH245Connection(call)== OO_FAILED)
1463       {
1464          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
1465                      call->callType, call->callToken);
1466
1467          if(call->callState < OO_CALL_CLEAR)
1468          {
1469             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
1470             call->callState = OO_CALL_CLEAR;
1471          }
1472          return OO_FAILED;
1473       }
1474    }
1475
1476    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent)
1477    {
1478       if (!q931Msg->userInfo->h323_uu_pdu.h245Tunneling)
1479       {
1480          if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1481          {
1482             OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1483             OOTRACEINFO3("Tunneling is disabled by remote endpoint.(%s, %s)\n",
1484                           call->callType, call->callToken);
1485          }
1486       }
1487    }
1488    if (OO_TESTFLAG(call->flags, OO_M_TUNNELING))
1489    {
1490       OOTRACEDBGB3("Handling tunneled messages in CONNECT. (%s, %s)\n",
1491                     call->callType, call->callToken);
1492       ret = ooHandleTunneledH245Messages
1493          (call, &q931Msg->userInfo->h323_uu_pdu);
1494       OOTRACEDBGB3("Finished tunneled messages in Connect. (%s, %s)\n",
1495                     call->callType, call->callToken);
1496
1497       /*
1498         Send TCS as call established and no capability exchange has yet 
1499         started. This will be true only when separate h245 connection is not
1500         established and tunneling is being used.
1501       */
1502       if(call->localTermCapState == OO_LocalTermCapExchange_Idle)
1503       {
1504          /*Start terminal capability exchange and master slave determination */
1505          ret = ooSendTermCapMsg(call);
1506          if(ret != OO_OK)
1507          {
1508             OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
1509                          call->callType, call->callToken);
1510             return ret;
1511          }
1512       }
1513       if(call->masterSlaveState == OO_MasterSlave_Idle)
1514       {
1515          ret = ooSendMasterSlaveDetermination(call);
1516          if(ret != OO_OK)
1517          {
1518             OOTRACEERR3("ERROR:Sending Master-slave determination message "
1519                      "(%s, %s)\n", call->callType, call->callToken);
1520             return ret;
1521          }   
1522       }
1523
1524    }
1525    return OO_OK;  
1526 }
1527
1528 int ooHandleH2250Message(OOH323CallData *call, Q931Message *q931Msg)
1529 {
1530    int ret=OO_OK;
1531    ASN1UINT i;
1532    DListNode *pNode = NULL;
1533    OOTimer *pTimer=NULL;
1534    int type = q931Msg->messageType;
1535    struct timespec ts;
1536
1537 /* checking of message validity for first/next messages of calls */
1538
1539    if (!strcmp(call->callType, "incoming")) {
1540         if ((call->callState != OO_CALL_CREATED && type == Q931SetupMsg) ||
1541             (call->callState == OO_CALL_CREATED && type != Q931SetupMsg)) {
1542                 ooFreeQ931Message(call->msgctxt, q931Msg);
1543                 return OO_FAILED;
1544         }
1545    }
1546
1547    switch(type)
1548    {
1549       case Q931SetupMsg: /* SETUP message is received */
1550          OOTRACEINFO3("Received SETUP message (%s, %s)\n", call->callType,
1551                        call->callToken);
1552          ooOnReceivedSetup(call, q931Msg);
1553
1554          /* H225 message callback */
1555          if(gH323ep.h225Callbacks.onReceivedSetup)
1556             ret = gH323ep.h225Callbacks.onReceivedSetup(call, q931Msg);
1557
1558          /* Free up the mem used by the received message, as it's processing 
1559             is done. 
1560          */
1561          if (ret == OO_OK) {
1562
1563          ooFreeQ931Message(call->msgctxt, q931Msg);
1564          
1565          /* DISABLEGK is used to selectively disable gatekeeper use. For 
1566             incoming calls DISABLEGK can be set in onReceivedSetup callback by 
1567             application. Very useful in pbx applications where gk is used only 
1568             when call is to or from outside pbx domian
1569          */
1570          if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
1571          {
1572             if(gH323ep.gkClient->state == GkClientRegistered)
1573             {
1574                call->callState = OO_CALL_WAITING_ADMISSION;
1575                ast_mutex_lock(&call->Lock);
1576                ret = ooGkClientSendAdmissionRequest(gH323ep.gkClient, call, 
1577                                                     FALSE);
1578                 clock_gettime(CLOCK_REALTIME, &ts);
1579                 ts.tv_sec += 24;
1580                 ast_cond_timedwait(&call->gkWait, &call->Lock, &ts);
1581                 if (call->callState == OO_CALL_WAITING_ADMISSION)
1582                         call->callState = OO_CALL_CLEAR;
1583                 ast_mutex_unlock(&call->Lock);
1584
1585             }
1586             else {
1587                /* TODO: Should send Release complete with reject reason */
1588                OOTRACEERR1("Error:Ignoring incoming call as not yet"
1589                            "registered with Gk\n");
1590                call->callState = OO_CALL_CLEAR;
1591             }
1592          }
1593          if (call->callState < OO_CALL_CLEAR) {
1594                 ooSendCallProceeding(call);/* Send call proceeding message*/
1595                 ret = ooH323CallAdmitted (call);
1596           }
1597
1598          call->callState = OO_CALL_CONNECTING;
1599
1600          } /* end ret == OO_OK */
1601          break;
1602
1603
1604       case Q931CallProceedingMsg: /* CALL PROCEEDING message is received */
1605          OOTRACEINFO3("H.225 Call Proceeding message received (%s, %s)\n",
1606                       call->callType, call->callToken);
1607          ooOnReceivedCallProceeding(call, q931Msg);
1608
1609          ooFreeQ931Message(call->msgctxt, q931Msg);
1610          break;
1611
1612
1613       case Q931AlertingMsg:/* ALERTING message received */
1614          OOTRACEINFO3("H.225 Alerting message received (%s, %s)\n", 
1615                       call->callType, call->callToken);
1616
1617          call->alertingTime = (H235TimeStamp) time(NULL);
1618          ooOnReceivedAlerting(call, q931Msg);
1619
1620          if(gH323ep.h323Callbacks.onAlerting && call->callState<OO_CALL_CLEAR)
1621             gH323ep.h323Callbacks.onAlerting(call);
1622          ooFreeQ931Message(call->msgctxt, q931Msg);
1623          break;
1624
1625
1626       case Q931ProgressMsg:/* PROGRESS message received */
1627          OOTRACEINFO3("H.225 Progress message received (%s, %s)\n", 
1628                       call->callType, call->callToken);
1629
1630          ooOnReceivedProgress(call, q931Msg);
1631
1632          if(gH323ep.h323Callbacks.onProgress && call->callState<OO_CALL_CLEAR)
1633             gH323ep.h323Callbacks.onProgress(call);
1634          ooFreeQ931Message(call->msgctxt, q931Msg);
1635          break;
1636
1637
1638       case Q931ConnectMsg:/* CONNECT message received */
1639          OOTRACEINFO3("H.225 Connect message received (%s, %s)\n",
1640                       call->callType, call->callToken);
1641
1642          call->connectTime = (H235TimeStamp) time(NULL);
1643
1644          /* Disable call establishment timer */
1645          for(i = 0; i<call->timerList.count; i++)
1646          {
1647             pNode = dListFindByIndex(&call->timerList, i);
1648             pTimer = (OOTimer*)pNode->data;
1649             if(((ooTimerCallback*)pTimer->cbData)->timerType & 
1650                                                          OO_CALLESTB_TIMER)
1651             {
1652                memFreePtr(call->pctxt, pTimer->cbData);
1653                ooTimerDelete(call->pctxt, &call->timerList, pTimer);
1654                OOTRACEDBGC3("Deleted CallESTB timer. (%s, %s)\n", 
1655                                               call->callType, call->callToken);
1656                break;
1657             }
1658          }
1659          ret = ooOnReceivedSignalConnect(call, q931Msg);
1660          if(ret != OO_OK)
1661             OOTRACEERR3("Error:Invalid Connect message received. (%s, %s)\n",
1662                         call->callType, call->callToken);
1663          else{
1664              /* H225 message callback */
1665             if(gH323ep.h225Callbacks.onReceivedConnect)
1666                gH323ep.h225Callbacks.onReceivedConnect(call, q931Msg);
1667
1668             if(gH323ep.h323Callbacks.onCallEstablished)
1669                gH323ep.h323Callbacks.onCallEstablished(call);
1670          }
1671          ooFreeQ931Message(call->msgctxt, q931Msg);
1672
1673          if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK)) {
1674             if(gH323ep.gkClient->state == GkClientRegistered) {
1675                 ooGkClientSendIRR(gH323ep.gkClient, call);
1676             }
1677          }
1678          break;
1679       case Q931InformationMsg:
1680          OOTRACEINFO3("H.225 Information msg received (%s, %s)\n",
1681                        call->callType, call->callToken);
1682          ooFreeQ931Message(call->msgctxt, q931Msg);
1683          break;
1684
1685
1686       case Q931ReleaseCompleteMsg:/* RELEASE COMPLETE message received */
1687          OOTRACEINFO3("H.225 Release Complete message received (%s, %s)\n",
1688                       call->callType, call->callToken);
1689
1690          call->endTime = (H235TimeStamp) time(NULL);
1691
1692          ooOnReceivedReleaseComplete(call, q931Msg);
1693          
1694          ooFreeQ931Message(call->msgctxt, q931Msg);
1695          break;
1696       case Q931FacilityMsg: 
1697          OOTRACEINFO3("H.225 Facility message Received (%s, %s)\n",
1698                        call->callType, call->callToken);
1699
1700          ooOnReceivedFacility(call, q931Msg); 
1701          ooFreeQ931Message(call->msgctxt, q931Msg);
1702          break;
1703       case Q931StatusMsg:
1704          OOTRACEINFO3("H.225 Status message received (%s, %s)\n",
1705                        call->callType, call->callToken);
1706          ooFreeQ931Message(call->msgctxt, q931Msg);
1707          break;
1708       case Q931StatusEnquiryMsg:
1709          OOTRACEINFO3("H.225 Status Inquiry message Received (%s, %s)\n",
1710                        call->callType, call->callToken);
1711          ooFreeQ931Message(call->msgctxt, q931Msg);
1712          break;
1713       case Q931SetupAckMsg:
1714          OOTRACEINFO3("H.225 Setup Ack message received (%s, %s)\n",
1715                        call->callType, call->callToken);
1716          ooFreeQ931Message(call->msgctxt, q931Msg);
1717          break;
1718       case Q931NotifyMsg: 
1719          OOTRACEINFO3("H.225 Notify message Received (%s, %s)\n",
1720                        call->callType, call->callToken);
1721          ooFreeQ931Message(call->msgctxt, q931Msg);
1722          break;
1723       default:
1724          OOTRACEWARN3("Invalid H.225 message type received (%s, %s)\n",
1725                       call->callType, call->callToken);
1726          ooFreeQ931Message(call->msgctxt, q931Msg);
1727    }
1728    return ret;
1729 }
1730
1731 int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
1732 {
1733    H225H323_UU_PDU * pH323UUPdu = NULL;
1734    H225Facility_UUIE * facility = NULL;
1735    int ret;
1736    H225TransportAddress_ipAddress_ip *ip = NULL;
1737    OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType, 
1738                                                         call->callToken);
1739    /* Get Reference to H323_UU_PDU */
1740    if(!pQ931Msg->userInfo)
1741    {
1742       OOTRACEERR3("Error: UserInfo not found in received H.225 Facility "
1743                   "message (%s, %s)\n", call->callType, call->callToken);
1744       return OO_FAILED;
1745    }
1746    pH323UUPdu = &pQ931Msg->userInfo->h323_uu_pdu;
1747    if(!pH323UUPdu)
1748    {
1749       OOTRACEERR1("ERROR: H225H323_UU_PDU absent in incoming facility "
1750                   "message\n");
1751       return OO_FAILED;
1752    }
1753    facility = pH323UUPdu->h323_message_body.u.facility;
1754    if(facility)
1755    {
1756       /* Depending on the reason of facility message handle the message */
1757       if(facility->reason.t == T_H225FacilityReason_transportedInformation)
1758       {
1759          if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1760          {
1761             OOTRACEDBGB3("Handling tunneled messages in Facility. (%s, %s)\n",
1762                call->callType, call->callToken);
1763             ooHandleTunneledH245Messages(call, pH323UUPdu);
1764             OOTRACEDBGB3("Finished handling tunneled messages in Facility."
1765                          "(%s, %s)\n",call->callType, call->callToken);
1766          }
1767          else
1768          {
1769             OOTRACEERR3("ERROR:Tunneled H.245 message received in facility. "
1770                         "Tunneling is disabled at local for this call (%s, %s)\n",
1771                         call->callType, call->callToken);
1772             return OO_FAILED;
1773          }
1774       }
1775       else if(facility->reason.t == T_H225FacilityReason_startH245)
1776       {
1777          OOTRACEINFO3("Remote wants to start a separate H.245 Channel "
1778                       "(%s, %s)\n", call->callType, call->callToken);
1779          /*start H.245 channel*/
1780          ret = ooHandleStartH245FacilityMessage(call, facility);
1781          if(ret != OO_OK)
1782          {
1783             OOTRACEERR3("ERROR: Handling startH245 facility message "
1784                         "(%s, %s)\n", call->callType, call->callToken);
1785             return ret;
1786          }
1787       }
1788       else if(facility->reason.t == T_H225FacilityReason_callForwarded)
1789       {
1790          OOTRACEINFO3("Call Forward Facility message received. (%s, %s)\n",
1791                       call->callType, call->callToken);
1792          if(!facility->m.alternativeAddressPresent && 
1793             !facility->m.alternativeAliasAddressPresent)
1794          {
1795             OOTRACEERR3("Error:No alternative address provided in call forward"
1796                        "facility message.(%s, %s)\n", call->callType, 
1797                         call->callToken);
1798             if(call->callState < OO_CALL_CLEAR)
1799             {
1800                call->callState = OO_CALL_CLEAR;
1801                call->callEndReason = OO_REASON_INVALIDMESSAGE;
1802             }
1803             return OO_OK;
1804          }
1805          call->pCallFwdData = (OOCallFwdData *) memAlloc(call->pctxt, 
1806                                                         sizeof(OOCallFwdData));
1807          if(!call->pCallFwdData)
1808          {
1809             OOTRACEERR3("Error:Memory - ooOnReceivedFacility - pCallFwdData "
1810                         "(%s, %s)\n", call->callType, call->callToken);
1811             return OO_FAILED;
1812          }
1813          call->pCallFwdData->fwdedByRemote = TRUE;
1814          call->pCallFwdData->ip[0]='\0';
1815          call->pCallFwdData->aliases = NULL;
1816          if(facility->m.alternativeAddressPresent)
1817          {
1818             if(facility->alternativeAddress.t != 
1819                                            T_H225TransportAddress_ipAddress)
1820             {
1821                OOTRACEERR3("ERROR: Source call signalling address type not ip "
1822                            "(%s, %s)\n", call->callType, call->callToken);
1823            
1824                return OO_FAILED;
1825             }
1826
1827             ip = &facility->alternativeAddress.u.ipAddress->ip;
1828             sprintf(call->pCallFwdData->ip, "%d.%d.%d.%d", ip->data[0], 
1829                                        ip->data[1], ip->data[2], ip->data[3]);
1830             call->pCallFwdData->port =  
1831                                facility->alternativeAddress.u.ipAddress->port;
1832          }
1833
1834          if(facility->m.alternativeAliasAddressPresent)
1835          {
1836             ooH323RetrieveAliases(call, &facility->alternativeAliasAddress, 
1837                                   &call->pCallFwdData->aliases);
1838          }
1839          /* Now we have to clear the current call and make a new call to
1840             fwded location*/
1841          if(call->callState < OO_CALL_CLEAR)
1842          {
1843             call->callState = OO_CALL_CLEAR;
1844             call->callEndReason = OO_REASON_REMOTE_FWDED;
1845          }
1846          else{
1847             OOTRACEERR3("Error:Can't forward call as it is being cleared."
1848                         " (%s, %s)\n", call->callType, call->callToken);
1849            return OO_OK;
1850          }
1851       }
1852       else if(facility->reason.t == T_H225FacilityReason_forwardedElements)
1853       {
1854          OOTRACEINFO3("Handling fast start in forwardedElem facility for "
1855                       "(%s, %s)\n", call->callType, call->callToken);
1856          /*start H.245 channel*/
1857          ret = ooHandleFastStart(call, facility);
1858          if(ret != OO_OK)
1859          {
1860             OOTRACEERR3("ERROR: Handling transportedInformation facility message "
1861                         "(%s, %s)\n", call->callType, call->callToken);
1862             return ret;
1863          }
1864       }
1865       else{
1866          OOTRACEINFO3("Unhandled Facility reason type received (%s, %s)\n", 
1867                        call->callType, call->callToken);
1868       }
1869    }
1870    else{ /* Empty facility message Check for tunneling */
1871       if (pH323UUPdu->h323_message_body.t == 
1872           T_H225H323_UU_PDU_h323_message_body_empty) {
1873       OOTRACEDBGB3("Handling tunneled messages in empty Facility message."
1874                    " (%s, %s)\n", call->callType, call->callToken);
1875       ooHandleTunneledH245Messages(call, pH323UUPdu);
1876       OOTRACEDBGB3("Finished handling tunneled messages in empty Facility "
1877                    "message. (%s, %s)\n", call->callType, call->callToken);
1878       }
1879    }
1880    
1881    return OO_OK;
1882 }
1883
1884 int ooHandleStartH245FacilityMessage
1885    (OOH323CallData *call, H225Facility_UUIE *facility)
1886 {
1887    H225TransportAddress_ipAddress *ipAddress = NULL;
1888    int ret;
1889    
1890    /* Extract H245 address */
1891    if(!facility->m.h245AddressPresent)
1892    {
1893       OOTRACEERR3("ERROR: startH245 facility message received with no h245 "
1894                   "address (%s, %s)\n", call->callType, call->callToken);
1895       return OO_FAILED;
1896    }
1897    if(facility->h245Address.t != T_H225TransportAddress_ipAddress)
1898    {
1899       OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
1900                "facility message (%s, %s)\n", call->callType, call->callToken);
1901       return OO_FAILED;
1902    }
1903    ipAddress = facility->h245Address.u.ipAddress;
1904    if(!ipAddress)
1905    {
1906       OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip "
1907                   "address found. (%s, %s)\n", call->callType, call->callToken);
1908       return OO_FAILED;
1909    }
1910    
1911    sprintf(call->remoteIP, "%d.%d.%d.%d", ipAddress->ip.data[0],
1912                                           ipAddress->ip.data[1],
1913                                           ipAddress->ip.data[2],
1914                                           ipAddress->ip.data[3]);
1915    call->remoteH245Port = ipAddress->port;
1916
1917    /* disable tunneling for this call */
1918    OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1919
1920    /*Establish an H.245 connection */
1921    ret = ooCreateH245Connection(call);
1922    if(ret != OO_OK)
1923    {
1924       OOTRACEERR3("ERROR: Failed to establish an H.245 connection with remote"
1925                   " endpoint (%s, %s)\n", call->callType, call->callToken);
1926       return ret;
1927    }
1928    return OO_OK;
1929 }
1930
1931 int ooHandleTunneledH245Messages
1932    (OOH323CallData *call, H225H323_UU_PDU * pH323UUPdu)
1933 {
1934    H245Message *pmsg;
1935    OOCTXT *pctxt = call->msgctxt;
1936    int ret=0,i=0;
1937    
1938    OOTRACEDBGC3("Checking for tunneled H.245 messages (%s, %s)\n", 
1939                  call->callType, call->callToken);
1940
1941    /* Check whether there are tunneled messages */  
1942    if(pH323UUPdu->m.h245TunnelingPresent)
1943    {
1944       if(pH323UUPdu->h245Tunneling)
1945       {
1946          OOTRACEDBGB4("Total number of tunneled H245 messages are %d.(%s, %s)"
1947                       "\n", (int)pH323UUPdu->h245Control.n, call->callType, 
1948                       call->callToken);
1949          for(i=0; i< (int)pH323UUPdu->h245Control.n; i++)
1950          {
1951             OOTRACEDBGC5("Retrieving %d of %d tunneled H.245 messages."
1952                          "(%s, %s)\n",i+1, pH323UUPdu->h245Control.n,
1953                          call->callType, call->callToken);
1954             pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
1955             if(!pmsg)
1956             {
1957                OOTRACEERR3("Error:Memory - ooHandleH245TunneledMessages - pmsg"
1958                           "(%s, %s)\n", call->callType, call->callToken);
1959                return OO_FAILED;
1960             }
1961
1962             setPERBuffer(pctxt, 
1963                          (ASN1OCTET*)pH323UUPdu->h245Control.elem[i].data,
1964                          pH323UUPdu->h245Control.elem[i].numocts, 1);  
1965
1966             initializePrintHandler(&printHandler, "Tunneled H.245 Message");
1967             memset(pmsg, 0, sizeof(H245Message));
1968             /* Set event handler */
1969             setEventHandler (pctxt, &printHandler);
1970             OOTRACEDBGC4("Decoding %d tunneled H245 message. (%s, %s)\n", 
1971                           i+1, call->callType, call->callToken);
1972             ret = asn1PD_H245MultimediaSystemControlMessage(pctxt, 
1973                                                             &(pmsg->h245Msg));
1974             if(ret != ASN_OK)
1975             {
1976                OOTRACEERR3("Error decoding H245 message (%s, %s)\n", 
1977                             call->callType, call->callToken);
1978                ooFreeH245Message(call,pmsg);
1979                return OO_FAILED;
1980             }
1981             finishPrint();
1982             removeEventHandler (pctxt);
1983             ooHandleH245Message(call, pmsg);
1984             memFreePtr(pctxt, pmsg);
1985             pmsg = NULL;
1986          }/* End of For loop */
1987       }/* End of if(h245Tunneling) */
1988    }
1989    return OO_OK;
1990 }
1991
1992 int ooH323RetrieveAliases
1993    (OOH323CallData *call, H225_SeqOfH225AliasAddress *pAddresses, 
1994     OOAliases **aliasList)
1995 {
1996    int i=0,j=0,k=0;
1997    DListNode* pNode=NULL;
1998    H225AliasAddress *pAliasAddress=NULL;
1999    OOAliases *newAlias=NULL;
2000    H225TransportAddress *pTransportAddrss=NULL;
2001
2002    if(!pAddresses)
2003    {
2004       OOTRACEWARN3("Warn:No Aliases present (%s, %s)\n", call->callType, 
2005                     call->callToken);
2006       return OO_OK;
2007    }
2008    /* check for aliases */
2009    if(pAddresses->count<=0)
2010       return OO_OK;
2011    
2012    for(i=0; i<(int)pAddresses->count; i++)
2013    {
2014       pNode = dListFindByIndex (pAddresses, i);
2015
2016       if(!pNode)
2017          continue;
2018
2019       pAliasAddress = (H225AliasAddress*)pNode->data;
2020
2021       if(!pAliasAddress)
2022          continue;
2023
2024       newAlias = (OOAliases*)memAlloc(call->pctxt, sizeof(OOAliases));
2025       if(!newAlias)
2026       {
2027          OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - newAlias "
2028                      "(%s, %s)\n", call->callType, call->callToken);
2029          return OO_FAILED;
2030       }
2031       memset(newAlias, 0, sizeof(OOAliases));
2032       switch(pAliasAddress->t)
2033       {
2034       case T_H225AliasAddress_dialedDigits:
2035          newAlias->type = T_H225AliasAddress_dialedDigits;
2036          newAlias->value = (char*) memAlloc(call->pctxt, 
2037                          strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2038          if(!newAlias->value)
2039          {
2040             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2041                         "newAlias->value(dialedDigits) (%s, %s)\n", 
2042                          call->callType, call->callToken);
2043             memFreePtr(call->pctxt, newAlias);  
2044             return OO_FAILED;
2045          }
2046
2047          memcpy(newAlias->value, pAliasAddress->u.dialedDigits,
2048                            strlen(pAliasAddress->u.dialedDigits)*sizeof(char));
2049          newAlias->value[strlen(pAliasAddress->u.dialedDigits)*sizeof(char)]='\0';
2050          break;
2051       case T_H225AliasAddress_h323_ID:
2052          newAlias->type = T_H225AliasAddress_h323_ID;
2053          newAlias->value = (char*)memAlloc(call->pctxt, 
2054                          (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2055          if(!newAlias->value)
2056          {
2057             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2058                         "newAlias->value(h323id) (%s, %s)\n", call->callType, 
2059                          call->callToken);
2060             memFreePtr(call->pctxt, newAlias);  
2061             return OO_FAILED;
2062          }
2063
2064          for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2065          {
2066             if(pAliasAddress->u.h323_ID.data[j] < 256)
2067             {
2068                newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2069             }
2070          }
2071          newAlias->value[k] = '\0';
2072          break;   
2073       case T_H225AliasAddress_url_ID:
2074          newAlias->type = T_H225AliasAddress_url_ID;
2075          newAlias->value = (char*)memAlloc(call->pctxt,
2076                               strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2077          if(!newAlias->value)
2078          {
2079             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2080                         "newAlias->value(urlid) (%s, %s)\n", call->callType, 
2081                          call->callToken);
2082             memFreePtr(call->pctxt, newAlias);  
2083             return OO_FAILED;
2084          }
2085
2086          memcpy(newAlias->value, pAliasAddress->u.url_ID,
2087                                strlen(pAliasAddress->u.url_ID)*sizeof(char));
2088          newAlias->value[strlen(pAliasAddress->u.url_ID)*sizeof(char)]='\0';
2089          break;
2090       case T_H225AliasAddress_transportID:
2091          newAlias->type = T_H225AliasAddress_transportID;
2092          pTransportAddrss = pAliasAddress->u.transportID;
2093          if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
2094          {
2095             OOTRACEERR3("Error:Alias transportID not an IP address"
2096                         "(%s, %s)\n", call->callType, call->callToken);
2097             memFreePtr(call->pctxt, newAlias);
2098             break;
2099          }
2100          /* hopefully ip:port value can't exceed more than 30 
2101             characters */
2102          newAlias->value = (char*)memAlloc(call->pctxt, 
2103                                                       30*sizeof(char));
2104          sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2105                                   pTransportAddrss->u.ipAddress->ip.data[0],
2106                                   pTransportAddrss->u.ipAddress->ip.data[1],
2107                                   pTransportAddrss->u.ipAddress->ip.data[2],
2108                                   pTransportAddrss->u.ipAddress->ip.data[3],
2109                                   pTransportAddrss->u.ipAddress->port);
2110          break;
2111       case T_H225AliasAddress_email_ID:
2112          newAlias->type = T_H225AliasAddress_email_ID;
2113          newAlias->value = (char*)memAlloc(call->pctxt, 
2114                              strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2115          if(!newAlias->value)
2116          {
2117             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2118                         "newAlias->value(emailid) (%s, %s)\n", call->callType, 
2119                          call->callToken);
2120             memFreePtr(call->pctxt, newAlias);  
2121             return OO_FAILED;
2122          }
2123
2124          memcpy(newAlias->value, pAliasAddress->u.email_ID,
2125                               strlen(pAliasAddress->u.email_ID)*sizeof(char));
2126          newAlias->value[strlen(pAliasAddress->u.email_ID)*sizeof(char)]='\0';
2127          break;
2128       default:
2129          OOTRACEERR3("Error:Unhandled Alias type (%s, %s)\n", 
2130                        call->callType, call->callToken);
2131          memFreePtr(call->pctxt, newAlias);
2132          continue;
2133       }
2134
2135       newAlias->next = *aliasList;
2136       *aliasList = newAlias;
2137
2138       newAlias = NULL;
2139      
2140      pAliasAddress = NULL;
2141      pNode = NULL;
2142    }/* endof: for */
2143    return OO_OK;
2144 }
2145
2146
2147 int ooPopulatePrefixList(OOCTXT *pctxt, OOAliases *pAliases,
2148                            H225_SeqOfH225SupportedPrefix *pPrefixList )
2149 {
2150    H225SupportedPrefix *pPrefixEntry=NULL;
2151    OOAliases * pAlias=NULL;
2152    ASN1BOOL bValid=FALSE;
2153
2154    dListInit(pPrefixList);
2155    if(pAliases)
2156    {
2157       pAlias = pAliases;
2158       while(pAlias)
2159       {
2160          pPrefixEntry = NULL;
2161          switch(pAlias->type)
2162          {
2163          case T_H225AliasAddress_dialedDigits:
2164             pPrefixEntry = (H225SupportedPrefix *)memAlloc(pctxt, 
2165                                                      sizeof(H225SupportedPrefix));
2166             if(!pPrefixEntry) {
2167                 OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - pAliasEntry\n");
2168                 return OO_FAILED;
2169             }
2170             pPrefixEntry->prefix.t = T_H225AliasAddress_dialedDigits;
2171             pPrefixEntry->prefix.u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2172                                                      strlen(pAlias->value)+1);
2173             if(!pPrefixEntry->prefix.u.dialedDigits) {
2174                OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - "
2175                            "dialedDigits\n");
2176                memFreePtr(pctxt, pPrefixEntry);
2177                return OO_FAILED;
2178             }
2179             strcpy(*(char**)&pPrefixEntry->prefix.u.dialedDigits, pAlias->value);
2180             bValid = TRUE;
2181             break;
2182          default:
2183             bValid = FALSE;                  
2184          }
2185          
2186          if(bValid)
2187             dListAppend( pctxt, pPrefixList, (void*)pPrefixEntry );
2188          
2189          pAlias = pAlias->next;
2190       }
2191    }
2192    return OO_OK;
2193 }
2194 int ooPopulateAliasList(OOCTXT *pctxt, OOAliases *pAliases,
2195                            H225_SeqOfH225AliasAddress *pAliasList )
2196 {
2197    H225AliasAddress *pAliasEntry=NULL;
2198    OOAliases * pAlias=NULL;
2199    ASN1BOOL bValid=FALSE;
2200    int i = 0;
2201
2202    dListInit(pAliasList);
2203    if(pAliases)
2204    {
2205       pAlias = pAliases;
2206       while(pAlias)
2207       {
2208          if (pAlias->value[0] == 0) {
2209           pAlias = pAlias->next;
2210           continue;
2211          }
2212          pAliasEntry = (H225AliasAddress*)memAlloc(pctxt, 
2213                                                      sizeof(H225AliasAddress));
2214          if(!pAliasEntry)
2215          {
2216             OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - pAliasEntry\n");
2217             return OO_FAILED;
2218          }
2219          switch(pAlias->type)
2220          {
2221          case T_H225AliasAddress_dialedDigits:
2222             pAliasEntry->t = T_H225AliasAddress_dialedDigits;
2223             pAliasEntry->u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2224                                                      strlen(pAlias->value)+1);
2225             if(!pAliasEntry->u.dialedDigits)
2226             {
2227                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - "
2228                            "dialedDigits\n");
2229                memFreePtr(pctxt, pAliasEntry);
2230                return OO_FAILED;
2231             }
2232             strcpy(*(char**)&pAliasEntry->u.dialedDigits, pAlias->value);
2233             bValid = TRUE;
2234             break;
2235          case T_H225AliasAddress_h323_ID:
2236             pAliasEntry->t = T_H225AliasAddress_h323_ID;
2237             pAliasEntry->u.h323_ID.nchars = strlen(pAlias->value);
2238             pAliasEntry->u.h323_ID.data = (ASN116BITCHAR*)memAllocZ
2239                      (pctxt, strlen(pAlias->value)*sizeof(ASN116BITCHAR));
2240             
2241             if(!pAliasEntry->u.h323_ID.data)
2242             {
2243                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - h323_id\n");
2244                memFreePtr(pctxt, pAliasEntry);
2245                return OO_FAILED;
2246             }
2247             for(i=0; *(pAlias->value+i) != '\0'; i++)
2248                pAliasEntry->u.h323_ID.data[i] =(ASN116BITCHAR)pAlias->value[i];
2249             bValid = TRUE;
2250             break;
2251          case T_H225AliasAddress_url_ID:
2252             pAliasEntry->t = T_H225AliasAddress_url_ID;
2253             pAliasEntry->u.url_ID = (ASN1IA5String)memAlloc(pctxt, 
2254                                                      strlen(pAlias->value)+1);
2255             if(!pAliasEntry->u.url_ID)
2256             {
2257                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - url_id\n");
2258                memFreePtr(pctxt, pAliasEntry);               
2259                return OO_FAILED;
2260             }
2261             strcpy(*(char**)&pAliasEntry->u.url_ID, pAlias->value);
2262             bValid = TRUE;
2263             break;
2264          case T_H225AliasAddress_email_ID:
2265             pAliasEntry->t = T_H225AliasAddress_email_ID;
2266             pAliasEntry->u.email_ID = (ASN1IA5String)memAlloc(pctxt, 
2267                                                      strlen(pAlias->value)+1);
2268             if(!pAliasEntry->u.email_ID)
2269             {
2270                OOTRACEERR1("ERROR: Failed to allocate memory for EmailID "
2271                            "alias entry \n");
2272                return OO_FAILED;
2273             }
2274             strcpy(*(char**)&pAliasEntry->u.email_ID, pAlias->value);
2275             bValid = TRUE;
2276             break;
2277          default:
2278             OOTRACEERR1("ERROR: Unhandled alias type\n");
2279             bValid = FALSE;                  
2280          }
2281          
2282          if(bValid)
2283             dListAppend( pctxt, pAliasList, (void*)pAliasEntry );
2284          else
2285             memFreePtr(pctxt, pAliasEntry);
2286          
2287          pAlias = pAlias->next;
2288       }
2289    }
2290    return OO_OK;
2291 }
2292
2293
2294 OOAliases* ooH323GetAliasFromList(OOAliases *aliasList, int type, char *value)
2295 {
2296
2297    OOAliases *pAlias = NULL;
2298
2299    if(!aliasList)
2300    {
2301       OOTRACEDBGC1("No alias List to search\n");
2302       return NULL;
2303    }
2304
2305    pAlias = aliasList;
2306
2307    while(pAlias)
2308    {
2309      if(type != 0 && value) { /* Search by type and value */
2310          if(pAlias->type == type && !strcmp(pAlias->value, value))
2311          {
2312             return pAlias;
2313          }
2314       }
2315       else if(type != 0 && !value) {/* search by type */
2316          if(pAlias->type == type)
2317             return pAlias;
2318       }
2319       else if(type == 0 && value) {/* search by value */
2320          if(!strcmp(pAlias->value, value))
2321             return pAlias;
2322       }
2323       else {
2324          OOTRACEDBGC1("No criteria to search the alias list\n");
2325          return NULL;
2326       }
2327       pAlias = pAlias->next;
2328    }
2329
2330    return NULL;
2331 }
2332
2333 OOAliases* ooH323AddAliasToList
2334 (OOAliases **pAliasList, OOCTXT *pctxt, H225AliasAddress *pAliasAddress)
2335 {
2336    int j=0,k=0;
2337    OOAliases *newAlias=NULL;
2338    H225TransportAddress *pTransportAddrss=NULL;
2339    
2340    newAlias = (OOAliases*) memAlloc(pctxt, sizeof(OOAliases));
2341    if(!newAlias)
2342    {
2343       OOTRACEERR1("Error: Failed to allocate memory for new alias to be added to the alias list\n");
2344       return NULL;
2345    }
2346    memset(newAlias, 0, sizeof(OOAliases));
2347
2348    switch(pAliasAddress->t)
2349    {
2350    case T_H225AliasAddress_dialedDigits:
2351       newAlias->type = T_H225AliasAddress_dialedDigits;
2352       newAlias->value = (char*) memAlloc(pctxt, strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2353       strcpy(newAlias->value, pAliasAddress->u.dialedDigits);
2354       break;
2355    case T_H225AliasAddress_h323_ID:
2356       newAlias->type = T_H225AliasAddress_h323_ID;
2357       newAlias->value = (char*)memAlloc(pctxt, 
2358                            (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2359
2360       for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2361       {
2362          if(pAliasAddress->u.h323_ID.data[j] < 256)
2363          {
2364             newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2365          }
2366       }
2367       newAlias->value[k] = '\0';
2368       break;   
2369    case T_H225AliasAddress_url_ID:
2370       newAlias->type = T_H225AliasAddress_url_ID;
2371       newAlias->value = (char*)memAlloc(pctxt,
2372                             strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2373
2374       strcpy(newAlias->value, pAliasAddress->u.url_ID);
2375       break;
2376    case T_H225AliasAddress_transportID:
2377       newAlias->type = T_H225AliasAddress_transportID;
2378       pTransportAddrss = pAliasAddress->u.transportID;
2379       if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
2380       {
2381          OOTRACEERR1("Error:Alias transportID not an IP address\n");
2382          memFreePtr(pctxt, newAlias);
2383          return NULL;
2384       }
2385       /* hopefully ip:port value can't exceed more than 30 
2386          characters */
2387       newAlias->value = (char*)memAlloc(pctxt, 
2388                                               30*sizeof(char));
2389       sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2390                                pTransportAddrss->u.ipAddress->ip.data[0],
2391                                pTransportAddrss->u.ipAddress->ip.data[1],
2392                                pTransportAddrss->u.ipAddress->ip.data[2],
2393                                pTransportAddrss->u.ipAddress->ip.data[3],
2394                                pTransportAddrss->u.ipAddress->port);
2395       break;
2396    case T_H225AliasAddress_email_ID:
2397       newAlias->type = T_H225AliasAddress_email_ID;
2398       newAlias->value = (char*)memAlloc(pctxt, 
2399                  strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2400
2401       strcpy(newAlias->value, pAliasAddress->u.email_ID);
2402       break;
2403    default:
2404       OOTRACEERR1("Error:Unhandled Alias type \n");
2405       memFreePtr(pctxt, newAlias);
2406       return NULL;
2407
2408    }
2409    newAlias->next = *pAliasList;
2410    *pAliasList= newAlias;
2411    return newAlias;
2412 }
2413
2414 int ooH323GetIpPortFromH225TransportAddress(struct OOH323CallData *call, 
2415    H225TransportAddress *h225Address, char *ip, int *port)
2416 {
2417    if(h225Address->t != T_H225TransportAddress_ipAddress)
2418    {
2419       OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
2420                    call->callToken);
2421       return OO_FAILED;
2422    }
2423    sprintf(ip, "%d.%d.%d.%d", 
2424               h225Address->u.ipAddress->ip.data[0], 
2425               h225Address->u.ipAddress->ip.data[1],
2426               h225Address->u.ipAddress->ip.data[2],
2427               h225Address->u.ipAddress->ip.data[3]);
2428    *port = h225Address->u.ipAddress->port;
2429    return OO_OK;
2430 }