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