AST_CONTROL_CONNECTED_LINE frame type processing added to setup DisplayIE field
[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          } /* end ret == OO_OK */
1599          break;
1600
1601
1602       case Q931CallProceedingMsg: /* CALL PROCEEDING message is received */
1603          OOTRACEINFO3("H.225 Call Proceeding message received (%s, %s)\n",
1604                       call->callType, call->callToken);
1605          ooOnReceivedCallProceeding(call, q931Msg);
1606
1607          ooFreeQ931Message(call->msgctxt, q931Msg);
1608          break;
1609
1610
1611       case Q931AlertingMsg:/* ALERTING message received */
1612          OOTRACEINFO3("H.225 Alerting message received (%s, %s)\n", 
1613                       call->callType, call->callToken);
1614
1615          call->alertingTime = (H235TimeStamp) time(NULL);
1616          ooOnReceivedAlerting(call, q931Msg);
1617
1618          if(gH323ep.h323Callbacks.onAlerting && call->callState<OO_CALL_CLEAR)
1619             gH323ep.h323Callbacks.onAlerting(call);
1620          ooFreeQ931Message(call->msgctxt, q931Msg);
1621          break;
1622
1623
1624       case Q931ProgressMsg:/* PROGRESS message received */
1625          OOTRACEINFO3("H.225 Progress message received (%s, %s)\n", 
1626                       call->callType, call->callToken);
1627
1628          ooOnReceivedProgress(call, q931Msg);
1629
1630          if(gH323ep.h323Callbacks.onProgress && call->callState<OO_CALL_CLEAR)
1631             gH323ep.h323Callbacks.onProgress(call);
1632          ooFreeQ931Message(call->msgctxt, q931Msg);
1633          break;
1634
1635
1636       case Q931ConnectMsg:/* CONNECT message received */
1637          OOTRACEINFO3("H.225 Connect message received (%s, %s)\n",
1638                       call->callType, call->callToken);
1639
1640          call->connectTime = (H235TimeStamp) time(NULL);
1641
1642          /* Disable call establishment timer */
1643          for(i = 0; i<call->timerList.count; i++)
1644          {
1645             pNode = dListFindByIndex(&call->timerList, i);
1646             pTimer = (OOTimer*)pNode->data;
1647             if(((ooTimerCallback*)pTimer->cbData)->timerType & 
1648                                                          OO_CALLESTB_TIMER)
1649             {
1650                memFreePtr(call->pctxt, pTimer->cbData);
1651                ooTimerDelete(call->pctxt, &call->timerList, pTimer);
1652                OOTRACEDBGC3("Deleted CallESTB timer. (%s, %s)\n", 
1653                                               call->callType, call->callToken);
1654                break;
1655             }
1656          }
1657          ret = ooOnReceivedSignalConnect(call, q931Msg);
1658          if(ret != OO_OK)
1659             OOTRACEERR3("Error:Invalid Connect message received. (%s, %s)\n",
1660                         call->callType, call->callToken);
1661          else{
1662              /* H225 message callback */
1663             if(gH323ep.h225Callbacks.onReceivedConnect)
1664                gH323ep.h225Callbacks.onReceivedConnect(call, q931Msg);
1665
1666             if(gH323ep.h323Callbacks.onCallEstablished)
1667                gH323ep.h323Callbacks.onCallEstablished(call);
1668          }
1669          ooFreeQ931Message(call->msgctxt, q931Msg);
1670
1671          if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK)) {
1672             if(gH323ep.gkClient->state == GkClientRegistered) {
1673                 ooGkClientSendIRR(gH323ep.gkClient, call);
1674             }
1675          }
1676          break;
1677       case Q931InformationMsg:
1678          OOTRACEINFO3("H.225 Information msg received (%s, %s)\n",
1679                        call->callType, call->callToken);
1680          ooFreeQ931Message(call->msgctxt, q931Msg);
1681          break;
1682
1683
1684       case Q931ReleaseCompleteMsg:/* RELEASE COMPLETE message received */
1685          OOTRACEINFO3("H.225 Release Complete message received (%s, %s)\n",
1686                       call->callType, call->callToken);
1687
1688          call->endTime = (H235TimeStamp) time(NULL);
1689
1690          ooOnReceivedReleaseComplete(call, q931Msg);
1691          
1692          ooFreeQ931Message(call->msgctxt, q931Msg);
1693          break;
1694       case Q931FacilityMsg: 
1695          OOTRACEINFO3("H.225 Facility message Received (%s, %s)\n",
1696                        call->callType, call->callToken);
1697
1698          ooOnReceivedFacility(call, q931Msg); 
1699          ooFreeQ931Message(call->msgctxt, q931Msg);
1700          break;
1701       case Q931StatusMsg:
1702          OOTRACEINFO3("H.225 Status message received (%s, %s)\n",
1703                        call->callType, call->callToken);
1704          ooFreeQ931Message(call->msgctxt, q931Msg);
1705          break;
1706       case Q931StatusEnquiryMsg:
1707          OOTRACEINFO3("H.225 Status Inquiry message Received (%s, %s)\n",
1708                        call->callType, call->callToken);
1709          ooFreeQ931Message(call->msgctxt, q931Msg);
1710          break;
1711       case Q931SetupAckMsg:
1712          OOTRACEINFO3("H.225 Setup Ack message received (%s, %s)\n",
1713                        call->callType, call->callToken);
1714          ooFreeQ931Message(call->msgctxt, q931Msg);
1715          break;
1716       case Q931NotifyMsg: 
1717          OOTRACEINFO3("H.225 Notify message Received (%s, %s)\n",
1718                        call->callType, call->callToken);
1719          ooFreeQ931Message(call->msgctxt, q931Msg);
1720          break;
1721       default:
1722          OOTRACEWARN3("Invalid H.225 message type received (%s, %s)\n",
1723                       call->callType, call->callToken);
1724          ooFreeQ931Message(call->msgctxt, q931Msg);
1725    }
1726    return ret;
1727 }
1728
1729 int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
1730 {
1731    H225H323_UU_PDU * pH323UUPdu = NULL;
1732    H225Facility_UUIE * facility = NULL;
1733    int ret;
1734    H225TransportAddress_ipAddress_ip *ip = NULL;
1735    OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType, 
1736                                                         call->callToken);
1737    /* Get Reference to H323_UU_PDU */
1738    if(!pQ931Msg->userInfo)
1739    {
1740       OOTRACEERR3("Error: UserInfo not found in received H.225 Facility "
1741                   "message (%s, %s)\n", call->callType, call->callToken);
1742       return OO_FAILED;
1743    }
1744    pH323UUPdu = &pQ931Msg->userInfo->h323_uu_pdu;
1745    if(!pH323UUPdu)
1746    {
1747       OOTRACEERR1("ERROR: H225H323_UU_PDU absent in incoming facility "
1748                   "message\n");
1749       return OO_FAILED;
1750    }
1751    facility = pH323UUPdu->h323_message_body.u.facility;
1752    if(facility)
1753    {
1754       /* Depending on the reason of facility message handle the message */
1755       if(facility->reason.t == T_H225FacilityReason_transportedInformation)
1756       {
1757          if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1758          {
1759             OOTRACEDBGB3("Handling tunneled messages in Facility. (%s, %s)\n",
1760                call->callType, call->callToken);
1761             ooHandleTunneledH245Messages(call, pH323UUPdu);
1762             OOTRACEDBGB3("Finished handling tunneled messages in Facility."
1763                          "(%s, %s)\n",call->callType, call->callToken);
1764          }
1765          else
1766          {
1767             OOTRACEERR3("ERROR:Tunneled H.245 message received in facility. "
1768                         "Tunneling is disabled at local for this call (%s, %s)\n",
1769                         call->callType, call->callToken);
1770             return OO_FAILED;
1771          }
1772       }
1773       else if(facility->reason.t == T_H225FacilityReason_startH245)
1774       {
1775          OOTRACEINFO3("Remote wants to start a separate H.245 Channel "
1776                       "(%s, %s)\n", call->callType, call->callToken);
1777          /*start H.245 channel*/
1778          ret = ooHandleStartH245FacilityMessage(call, facility);
1779          if(ret != OO_OK)
1780          {
1781             OOTRACEERR3("ERROR: Handling startH245 facility message "
1782                         "(%s, %s)\n", call->callType, call->callToken);
1783             return ret;
1784          }
1785       }
1786       else if(facility->reason.t == T_H225FacilityReason_callForwarded)
1787       {
1788          OOTRACEINFO3("Call Forward Facility message received. (%s, %s)\n",
1789                       call->callType, call->callToken);
1790          if(!facility->m.alternativeAddressPresent && 
1791             !facility->m.alternativeAliasAddressPresent)
1792          {
1793             OOTRACEERR3("Error:No alternative address provided in call forward"
1794                        "facility message.(%s, %s)\n", call->callType, 
1795                         call->callToken);
1796             if(call->callState < OO_CALL_CLEAR)
1797             {
1798                call->callState = OO_CALL_CLEAR;
1799                call->callEndReason = OO_REASON_INVALIDMESSAGE;
1800             }
1801             return OO_OK;
1802          }
1803          call->pCallFwdData = (OOCallFwdData *) memAlloc(call->pctxt, 
1804                                                         sizeof(OOCallFwdData));
1805          if(!call->pCallFwdData)
1806          {
1807             OOTRACEERR3("Error:Memory - ooOnReceivedFacility - pCallFwdData "
1808                         "(%s, %s)\n", call->callType, call->callToken);
1809             return OO_FAILED;
1810          }
1811          call->pCallFwdData->fwdedByRemote = TRUE;
1812          call->pCallFwdData->ip[0]='\0';
1813          call->pCallFwdData->aliases = NULL;
1814          if(facility->m.alternativeAddressPresent)
1815          {
1816             if(facility->alternativeAddress.t != 
1817                                            T_H225TransportAddress_ipAddress)
1818             {
1819                OOTRACEERR3("ERROR: Source call signalling address type not ip "
1820                            "(%s, %s)\n", call->callType, call->callToken);
1821            
1822                return OO_FAILED;
1823             }
1824
1825             ip = &facility->alternativeAddress.u.ipAddress->ip;
1826             sprintf(call->pCallFwdData->ip, "%d.%d.%d.%d", ip->data[0], 
1827                                        ip->data[1], ip->data[2], ip->data[3]);
1828             call->pCallFwdData->port =  
1829                                facility->alternativeAddress.u.ipAddress->port;
1830          }
1831
1832          if(facility->m.alternativeAliasAddressPresent)
1833          {
1834             ooH323RetrieveAliases(call, &facility->alternativeAliasAddress, 
1835                                   &call->pCallFwdData->aliases);
1836          }
1837          /* Now we have to clear the current call and make a new call to
1838             fwded location*/
1839          if(call->callState < OO_CALL_CLEAR)
1840          {
1841             call->callState = OO_CALL_CLEAR;
1842             call->callEndReason = OO_REASON_REMOTE_FWDED;
1843          }
1844          else{
1845             OOTRACEERR3("Error:Can't forward call as it is being cleared."
1846                         " (%s, %s)\n", call->callType, call->callToken);
1847            return OO_OK;
1848          }
1849       }
1850       else if(facility->reason.t == T_H225FacilityReason_forwardedElements)
1851       {
1852          OOTRACEINFO3("Handling fast start in forwardedElem facility for "
1853                       "(%s, %s)\n", call->callType, call->callToken);
1854          /*start H.245 channel*/
1855          ret = ooHandleFastStart(call, facility);
1856          if(ret != OO_OK)
1857          {
1858             OOTRACEERR3("ERROR: Handling transportedInformation facility message "
1859                         "(%s, %s)\n", call->callType, call->callToken);
1860             return ret;
1861          }
1862       }
1863       else{
1864          OOTRACEINFO3("Unhandled Facility reason type received (%s, %s)\n", 
1865                        call->callType, call->callToken);
1866       }
1867    }
1868    else{ /* Empty facility message Check for tunneling */
1869       if (pH323UUPdu->h323_message_body.t == 
1870           T_H225H323_UU_PDU_h323_message_body_empty) {
1871       OOTRACEDBGB3("Handling tunneled messages in empty Facility message."
1872                    " (%s, %s)\n", call->callType, call->callToken);
1873       ooHandleTunneledH245Messages(call, pH323UUPdu);
1874       OOTRACEDBGB3("Finished handling tunneled messages in empty Facility "
1875                    "message. (%s, %s)\n", call->callType, call->callToken);
1876       }
1877    }
1878    
1879    return OO_OK;
1880 }
1881
1882 int ooHandleStartH245FacilityMessage
1883    (OOH323CallData *call, H225Facility_UUIE *facility)
1884 {
1885    H225TransportAddress_ipAddress *ipAddress = NULL;
1886    int ret;
1887    
1888    /* Extract H245 address */
1889    if(!facility->m.h245AddressPresent)
1890    {
1891       OOTRACEERR3("ERROR: startH245 facility message received with no h245 "
1892                   "address (%s, %s)\n", call->callType, call->callToken);
1893       return OO_FAILED;
1894    }
1895    if(facility->h245Address.t != T_H225TransportAddress_ipAddress)
1896    {
1897       OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
1898                "facility message (%s, %s)\n", call->callType, call->callToken);
1899       return OO_FAILED;
1900    }
1901    ipAddress = facility->h245Address.u.ipAddress;
1902    if(!ipAddress)
1903    {
1904       OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip "
1905                   "address found. (%s, %s)\n", call->callType, call->callToken);
1906       return OO_FAILED;
1907    }
1908    
1909    sprintf(call->remoteIP, "%d.%d.%d.%d", ipAddress->ip.data[0],
1910                                           ipAddress->ip.data[1],
1911                                           ipAddress->ip.data[2],
1912                                           ipAddress->ip.data[3]);
1913    call->remoteH245Port = ipAddress->port;
1914
1915    /* disable tunneling for this call */
1916    OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1917
1918    /*Establish an H.245 connection */
1919    ret = ooCreateH245Connection(call);
1920    if(ret != OO_OK)
1921    {
1922       OOTRACEERR3("ERROR: Failed to establish an H.245 connection with remote"
1923                   " endpoint (%s, %s)\n", call->callType, call->callToken);
1924       return ret;
1925    }
1926    return OO_OK;
1927 }
1928
1929 int ooHandleTunneledH245Messages
1930    (OOH323CallData *call, H225H323_UU_PDU * pH323UUPdu)
1931 {
1932    H245Message *pmsg;
1933    OOCTXT *pctxt = call->msgctxt;
1934    int ret=0,i=0;
1935    
1936    OOTRACEDBGC3("Checking for tunneled H.245 messages (%s, %s)\n", 
1937                  call->callType, call->callToken);
1938
1939    /* Check whether there are tunneled messages */  
1940    if(pH323UUPdu->m.h245TunnelingPresent)
1941    {
1942       if(pH323UUPdu->h245Tunneling)
1943       {
1944          OOTRACEDBGB4("Total number of tunneled H245 messages are %d.(%s, %s)"
1945                       "\n", (int)pH323UUPdu->h245Control.n, call->callType, 
1946                       call->callToken);
1947          for(i=0; i< (int)pH323UUPdu->h245Control.n; i++)
1948          {
1949             OOTRACEDBGC5("Retrieving %d of %d tunneled H.245 messages."
1950                          "(%s, %s)\n",i+1, pH323UUPdu->h245Control.n,
1951                          call->callType, call->callToken);
1952             pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
1953             if(!pmsg)
1954             {
1955                OOTRACEERR3("Error:Memory - ooHandleH245TunneledMessages - pmsg"
1956                           "(%s, %s)\n", call->callType, call->callToken);
1957                return OO_FAILED;
1958             }
1959
1960             setPERBuffer(pctxt, 
1961                          (ASN1OCTET*)pH323UUPdu->h245Control.elem[i].data,
1962                          pH323UUPdu->h245Control.elem[i].numocts, 1);  
1963
1964             initializePrintHandler(&printHandler, "Tunneled H.245 Message");
1965             memset(pmsg, 0, sizeof(H245Message));
1966             /* Set event handler */
1967             setEventHandler (pctxt, &printHandler);
1968             OOTRACEDBGC4("Decoding %d tunneled H245 message. (%s, %s)\n", 
1969                           i+1, call->callType, call->callToken);
1970             ret = asn1PD_H245MultimediaSystemControlMessage(pctxt, 
1971                                                             &(pmsg->h245Msg));
1972             if(ret != ASN_OK)
1973             {
1974                OOTRACEERR3("Error decoding H245 message (%s, %s)\n", 
1975                             call->callType, call->callToken);
1976                ooFreeH245Message(call,pmsg);
1977                return OO_FAILED;
1978             }
1979             finishPrint();
1980             removeEventHandler (pctxt);
1981             ooHandleH245Message(call, pmsg);
1982             memFreePtr(pctxt, pmsg);
1983             pmsg = NULL;
1984          }/* End of For loop */
1985       }/* End of if(h245Tunneling) */
1986    }
1987    return OO_OK;
1988 }
1989
1990 int ooH323RetrieveAliases
1991    (OOH323CallData *call, H225_SeqOfH225AliasAddress *pAddresses, 
1992     OOAliases **aliasList)
1993 {
1994    int i=0,j=0,k=0;
1995    DListNode* pNode=NULL;
1996    H225AliasAddress *pAliasAddress=NULL;
1997    OOAliases *newAlias=NULL;
1998    H225TransportAddress *pTransportAddrss=NULL;
1999
2000    if(!pAddresses)
2001    {
2002       OOTRACEWARN3("Warn:No Aliases present (%s, %s)\n", call->callType, 
2003                     call->callToken);
2004       return OO_OK;
2005    }
2006    /* check for aliases */
2007    if(pAddresses->count<=0)
2008       return OO_OK;
2009    
2010    for(i=0; i<(int)pAddresses->count; i++)
2011    {
2012       pNode = dListFindByIndex (pAddresses, i);
2013
2014       if(!pNode)
2015          continue;
2016
2017       pAliasAddress = (H225AliasAddress*)pNode->data;
2018
2019       if(!pAliasAddress)
2020          continue;
2021
2022       newAlias = (OOAliases*)memAlloc(call->pctxt, sizeof(OOAliases));
2023       if(!newAlias)
2024       {
2025          OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - newAlias "
2026                      "(%s, %s)\n", call->callType, call->callToken);
2027          return OO_FAILED;
2028       }
2029       memset(newAlias, 0, sizeof(OOAliases));
2030       switch(pAliasAddress->t)
2031       {
2032       case T_H225AliasAddress_dialedDigits:
2033          newAlias->type = T_H225AliasAddress_dialedDigits;
2034          newAlias->value = (char*) memAlloc(call->pctxt, 
2035                          strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2036          if(!newAlias->value)
2037          {
2038             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2039                         "newAlias->value(dialedDigits) (%s, %s)\n", 
2040                          call->callType, call->callToken);
2041             memFreePtr(call->pctxt, newAlias);  
2042             return OO_FAILED;
2043          }
2044
2045          memcpy(newAlias->value, pAliasAddress->u.dialedDigits,
2046                            strlen(pAliasAddress->u.dialedDigits)*sizeof(char));
2047          newAlias->value[strlen(pAliasAddress->u.dialedDigits)*sizeof(char)]='\0';
2048          break;
2049       case T_H225AliasAddress_h323_ID:
2050          newAlias->type = T_H225AliasAddress_h323_ID;
2051          newAlias->value = (char*)memAlloc(call->pctxt, 
2052                          (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2053          if(!newAlias->value)
2054          {
2055             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2056                         "newAlias->value(h323id) (%s, %s)\n", call->callType, 
2057                          call->callToken);
2058             memFreePtr(call->pctxt, newAlias);  
2059             return OO_FAILED;
2060          }
2061
2062          for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2063          {
2064             if(pAliasAddress->u.h323_ID.data[j] < 256)
2065             {
2066                newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2067             }
2068          }
2069          newAlias->value[k] = '\0';
2070          break;   
2071       case T_H225AliasAddress_url_ID:
2072          newAlias->type = T_H225AliasAddress_url_ID;
2073          newAlias->value = (char*)memAlloc(call->pctxt,
2074                               strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2075          if(!newAlias->value)
2076          {
2077             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2078                         "newAlias->value(urlid) (%s, %s)\n", call->callType, 
2079                          call->callToken);
2080             memFreePtr(call->pctxt, newAlias);  
2081             return OO_FAILED;
2082          }
2083
2084          memcpy(newAlias->value, pAliasAddress->u.url_ID,
2085                                strlen(pAliasAddress->u.url_ID)*sizeof(char));
2086          newAlias->value[strlen(pAliasAddress->u.url_ID)*sizeof(char)]='\0';
2087          break;
2088       case T_H225AliasAddress_transportID:
2089          newAlias->type = T_H225AliasAddress_transportID;
2090          pTransportAddrss = pAliasAddress->u.transportID;
2091          if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
2092          {
2093             OOTRACEERR3("Error:Alias transportID not an IP address"
2094                         "(%s, %s)\n", call->callType, call->callToken);
2095             memFreePtr(call->pctxt, newAlias);
2096             break;
2097          }
2098          /* hopefully ip:port value can't exceed more than 30 
2099             characters */
2100          newAlias->value = (char*)memAlloc(call->pctxt, 
2101                                                       30*sizeof(char));
2102          sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2103                                   pTransportAddrss->u.ipAddress->ip.data[0],
2104                                   pTransportAddrss->u.ipAddress->ip.data[1],
2105                                   pTransportAddrss->u.ipAddress->ip.data[2],
2106                                   pTransportAddrss->u.ipAddress->ip.data[3],
2107                                   pTransportAddrss->u.ipAddress->port);
2108          break;
2109       case T_H225AliasAddress_email_ID:
2110          newAlias->type = T_H225AliasAddress_email_ID;
2111          newAlias->value = (char*)memAlloc(call->pctxt, 
2112                              strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2113          if(!newAlias->value)
2114          {
2115             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
2116                         "newAlias->value(emailid) (%s, %s)\n", call->callType, 
2117                          call->callToken);
2118             memFreePtr(call->pctxt, newAlias);  
2119             return OO_FAILED;
2120          }
2121
2122          memcpy(newAlias->value, pAliasAddress->u.email_ID,
2123                               strlen(pAliasAddress->u.email_ID)*sizeof(char));
2124          newAlias->value[strlen(pAliasAddress->u.email_ID)*sizeof(char)]='\0';
2125          break;
2126       default:
2127          OOTRACEERR3("Error:Unhandled Alias type (%s, %s)\n", 
2128                        call->callType, call->callToken);
2129          memFreePtr(call->pctxt, newAlias);
2130          continue;
2131       }
2132
2133       newAlias->next = *aliasList;
2134       *aliasList = newAlias;
2135
2136       newAlias = NULL;
2137      
2138      pAliasAddress = NULL;
2139      pNode = NULL;
2140    }/* endof: for */
2141    return OO_OK;
2142 }
2143
2144
2145 int ooPopulatePrefixList(OOCTXT *pctxt, OOAliases *pAliases,
2146                            H225_SeqOfH225SupportedPrefix *pPrefixList )
2147 {
2148    H225SupportedPrefix *pPrefixEntry=NULL;
2149    OOAliases * pAlias=NULL;
2150    ASN1BOOL bValid=FALSE;
2151
2152    dListInit(pPrefixList);
2153    if(pAliases)
2154    {
2155       pAlias = pAliases;
2156       while(pAlias)
2157       {
2158          pPrefixEntry = NULL;
2159          switch(pAlias->type)
2160          {
2161          case T_H225AliasAddress_dialedDigits:
2162             pPrefixEntry = (H225SupportedPrefix *)memAlloc(pctxt, 
2163                                                      sizeof(H225SupportedPrefix));
2164             if(!pPrefixEntry) {
2165                 OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - pAliasEntry\n");
2166                 return OO_FAILED;
2167             }
2168             pPrefixEntry->prefix.t = T_H225AliasAddress_dialedDigits;
2169             pPrefixEntry->prefix.u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2170                                                      strlen(pAlias->value)+1);
2171             if(!pPrefixEntry->prefix.u.dialedDigits) {
2172                OOTRACEERR1("ERROR:Memory - ooPopulatePrefixList - "
2173                            "dialedDigits\n");
2174                memFreePtr(pctxt, pPrefixEntry);
2175                return OO_FAILED;
2176             }
2177             strcpy(*(char**)&pPrefixEntry->prefix.u.dialedDigits, pAlias->value);
2178             bValid = TRUE;
2179             break;
2180          default:
2181             bValid = FALSE;                  
2182          }
2183          
2184          if(bValid)
2185             dListAppend( pctxt, pPrefixList, (void*)pPrefixEntry );
2186          
2187          pAlias = pAlias->next;
2188       }
2189    }
2190    return OO_OK;
2191 }
2192 int ooPopulateAliasList(OOCTXT *pctxt, OOAliases *pAliases,
2193                            H225_SeqOfH225AliasAddress *pAliasList )
2194 {
2195    H225AliasAddress *pAliasEntry=NULL;
2196    OOAliases * pAlias=NULL;
2197    ASN1BOOL bValid=FALSE;
2198    int i = 0;
2199
2200    dListInit(pAliasList);
2201    if(pAliases)
2202    {
2203       pAlias = pAliases;
2204       while(pAlias)
2205       {
2206          if (pAlias->value[0] == 0) {
2207           pAlias = pAlias->next;
2208           continue;
2209          }
2210          pAliasEntry = (H225AliasAddress*)memAlloc(pctxt, 
2211                                                      sizeof(H225AliasAddress));
2212          if(!pAliasEntry)
2213          {
2214             OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - pAliasEntry\n");
2215             return OO_FAILED;
2216          }
2217          switch(pAlias->type)
2218          {
2219          case T_H225AliasAddress_dialedDigits:
2220             pAliasEntry->t = T_H225AliasAddress_dialedDigits;
2221             pAliasEntry->u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
2222                                                      strlen(pAlias->value)+1);
2223             if(!pAliasEntry->u.dialedDigits)
2224             {
2225                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - "
2226                            "dialedDigits\n");
2227                memFreePtr(pctxt, pAliasEntry);
2228                return OO_FAILED;
2229             }
2230             strcpy(*(char**)&pAliasEntry->u.dialedDigits, pAlias->value);
2231             bValid = TRUE;
2232             break;
2233          case T_H225AliasAddress_h323_ID:
2234             pAliasEntry->t = T_H225AliasAddress_h323_ID;
2235             pAliasEntry->u.h323_ID.nchars = strlen(pAlias->value);
2236             pAliasEntry->u.h323_ID.data = (ASN116BITCHAR*)memAllocZ
2237                      (pctxt, strlen(pAlias->value)*sizeof(ASN116BITCHAR));
2238             
2239             if(!pAliasEntry->u.h323_ID.data)
2240             {
2241                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - h323_id\n");
2242                memFreePtr(pctxt, pAliasEntry);
2243                return OO_FAILED;
2244             }
2245             for(i=0; *(pAlias->value+i) != '\0'; i++)
2246                pAliasEntry->u.h323_ID.data[i] =(ASN116BITCHAR)pAlias->value[i];
2247             bValid = TRUE;
2248             break;
2249          case T_H225AliasAddress_url_ID:
2250             pAliasEntry->t = T_H225AliasAddress_url_ID;
2251             pAliasEntry->u.url_ID = (ASN1IA5String)memAlloc(pctxt, 
2252                                                      strlen(pAlias->value)+1);
2253             if(!pAliasEntry->u.url_ID)
2254             {
2255                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - url_id\n");
2256                memFreePtr(pctxt, pAliasEntry);               
2257                return OO_FAILED;
2258             }
2259             strcpy(*(char**)&pAliasEntry->u.url_ID, pAlias->value);
2260             bValid = TRUE;
2261             break;
2262          case T_H225AliasAddress_email_ID:
2263             pAliasEntry->t = T_H225AliasAddress_email_ID;
2264             pAliasEntry->u.email_ID = (ASN1IA5String)memAlloc(pctxt, 
2265                                                      strlen(pAlias->value)+1);
2266             if(!pAliasEntry->u.email_ID)
2267             {
2268                OOTRACEERR1("ERROR: Failed to allocate memory for EmailID "
2269                            "alias entry \n");
2270                return OO_FAILED;
2271             }
2272             strcpy(*(char**)&pAliasEntry->u.email_ID, pAlias->value);
2273             bValid = TRUE;
2274             break;
2275          default:
2276             OOTRACEERR1("ERROR: Unhandled alias type\n");
2277             bValid = FALSE;                  
2278          }
2279          
2280          if(bValid)
2281             dListAppend( pctxt, pAliasList, (void*)pAliasEntry );
2282          else
2283             memFreePtr(pctxt, pAliasEntry);
2284          
2285          pAlias = pAlias->next;
2286       }
2287    }
2288    return OO_OK;
2289 }
2290
2291
2292 OOAliases* ooH323GetAliasFromList(OOAliases *aliasList, int type, char *value)
2293 {
2294
2295    OOAliases *pAlias = NULL;
2296
2297    if(!aliasList)
2298    {
2299       OOTRACEDBGC1("No alias List to search\n");
2300       return NULL;
2301    }
2302
2303    pAlias = aliasList;
2304
2305    while(pAlias)
2306    {
2307      if(type != 0 && value) { /* Search by type and value */
2308          if(pAlias->type == type && !strcmp(pAlias->value, value))
2309          {
2310             return pAlias;
2311          }
2312       }
2313       else if(type != 0 && !value) {/* search by type */
2314          if(pAlias->type == type)
2315             return pAlias;
2316       }
2317       else if(type == 0 && value) {/* search by value */
2318          if(!strcmp(pAlias->value, value))
2319             return pAlias;
2320       }
2321       else {
2322          OOTRACEDBGC1("No criteria to search the alias list\n");
2323          return NULL;
2324       }
2325       pAlias = pAlias->next;
2326    }
2327
2328    return NULL;
2329 }
2330
2331 OOAliases* ooH323AddAliasToList
2332 (OOAliases **pAliasList, OOCTXT *pctxt, H225AliasAddress *pAliasAddress)
2333 {
2334    int j=0,k=0;
2335    OOAliases *newAlias=NULL;
2336    H225TransportAddress *pTransportAddrss=NULL;
2337    
2338    newAlias = (OOAliases*) memAlloc(pctxt, sizeof(OOAliases));
2339    if(!newAlias)
2340    {
2341       OOTRACEERR1("Error: Failed to allocate memory for new alias to be added to the alias list\n");
2342       return NULL;
2343    }
2344    memset(newAlias, 0, sizeof(OOAliases));
2345
2346    switch(pAliasAddress->t)
2347    {
2348    case T_H225AliasAddress_dialedDigits:
2349       newAlias->type = T_H225AliasAddress_dialedDigits;
2350       newAlias->value = (char*) memAlloc(pctxt, strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
2351       strcpy(newAlias->value, pAliasAddress->u.dialedDigits);
2352       break;
2353    case T_H225AliasAddress_h323_ID:
2354       newAlias->type = T_H225AliasAddress_h323_ID;
2355       newAlias->value = (char*)memAlloc(pctxt, 
2356                            (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
2357
2358       for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
2359       {
2360          if(pAliasAddress->u.h323_ID.data[j] < 256)
2361          {
2362             newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
2363          }
2364       }
2365       newAlias->value[k] = '\0';
2366       break;   
2367    case T_H225AliasAddress_url_ID:
2368       newAlias->type = T_H225AliasAddress_url_ID;
2369       newAlias->value = (char*)memAlloc(pctxt,
2370                             strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
2371
2372       strcpy(newAlias->value, pAliasAddress->u.url_ID);
2373       break;
2374    case T_H225AliasAddress_transportID:
2375       newAlias->type = T_H225AliasAddress_transportID;
2376       pTransportAddrss = pAliasAddress->u.transportID;
2377       if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
2378       {
2379          OOTRACEERR1("Error:Alias transportID not an IP address\n");
2380          memFreePtr(pctxt, newAlias);
2381          return NULL;
2382       }
2383       /* hopefully ip:port value can't exceed more than 30 
2384          characters */
2385       newAlias->value = (char*)memAlloc(pctxt, 
2386                                               30*sizeof(char));
2387       sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
2388                                pTransportAddrss->u.ipAddress->ip.data[0],
2389                                pTransportAddrss->u.ipAddress->ip.data[1],
2390                                pTransportAddrss->u.ipAddress->ip.data[2],
2391                                pTransportAddrss->u.ipAddress->ip.data[3],
2392                                pTransportAddrss->u.ipAddress->port);
2393       break;
2394    case T_H225AliasAddress_email_ID:
2395       newAlias->type = T_H225AliasAddress_email_ID;
2396       newAlias->value = (char*)memAlloc(pctxt, 
2397                  strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
2398
2399       strcpy(newAlias->value, pAliasAddress->u.email_ID);
2400       break;
2401    default:
2402       OOTRACEERR1("Error:Unhandled Alias type \n");
2403       memFreePtr(pctxt, newAlias);
2404       return NULL;
2405
2406    }
2407    newAlias->next = *pAliasList;
2408    *pAliasList= newAlias;
2409    return newAlias;
2410 }
2411
2412 int ooH323GetIpPortFromH225TransportAddress(struct OOH323CallData *call, 
2413    H225TransportAddress *h225Address, char *ip, int *port)
2414 {
2415    if(h225Address->t != T_H225TransportAddress_ipAddress)
2416    {
2417       OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
2418                    call->callToken);
2419       return OO_FAILED;
2420    }
2421    sprintf(ip, "%d.%d.%d.%d", 
2422               h225Address->u.ipAddress->ip.data[0], 
2423               h225Address->u.ipAddress->ip.data[1],
2424               h225Address->u.ipAddress->ip.data[2],
2425               h225Address->u.ipAddress->ip.data[3]);
2426    *port = h225Address->u.ipAddress->port;
2427    return OO_OK;
2428 }