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