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