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