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