Move Asterisk-addons modules into the main Asterisk source tree.
[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 "ootypes.h"
18 #include "ooq931.h"
19 #include "ootrace.h"
20 #include "oochannels.h"
21 #include "ooh245.h"
22 #include "ooCalls.h"
23 #include "printHandler.h"
24 #include "ooh323.h"
25 #include "ooh323ep.h"
26 #include "ooGkClient.h"
27 #include "ooTimer.h"
28
29 /** Global endpoint structure */
30 extern OOH323EndPoint gH323ep;
31
32
33 int ooOnReceivedReleaseComplete(OOH323CallData *call, Q931Message *q931Msg)
34 {
35    int ret = OO_OK;
36    H225ReleaseComplete_UUIE * releaseComplete = NULL;
37    ASN1UINT i;
38    DListNode *pNode = NULL;
39    OOTimer *pTimer = NULL;
40    unsigned reasonCode=T_H225ReleaseCompleteReason_undefinedReason;
41    enum Q931CauseValues cause= Q931ErrorInCauseIE;
42
43    if(q931Msg->causeIE)
44    {
45       cause = q931Msg->causeIE->data[1];
46       /* Get rid of the extension bit.For more info, check ooQ931SetCauseIE */
47       cause = cause & 0x7f; 
48       OOTRACEDBGA4("Cause of Release Complete is %x. (%s, %s)\n", cause, 
49                                              call->callType, call->callToken);
50    }
51
52    /* Remove session timer, if active*/
53    for(i = 0; i<call->timerList.count; i++)
54    {
55       pNode = dListFindByIndex(&call->timerList, i);
56       pTimer = (OOTimer*)pNode->data;
57       if(((ooTimerCallback*)pTimer->cbData)->timerType & 
58                                                    OO_SESSION_TIMER)
59       {
60          memFreePtr(call->pctxt, pTimer->cbData);
61          ooTimerDelete(call->pctxt, &call->timerList, pTimer);
62          OOTRACEDBGC3("Deleted Session Timer. (%s, %s)\n", 
63                        call->callType, call->callToken);
64          break;
65       }
66    }
67
68  
69    if(!q931Msg->userInfo)
70    {
71       OOTRACEERR3("ERROR:No User-User IE in received ReleaseComplete message "
72                   "(%s, %s)\n", call->callType, call->callToken);
73       return OO_FAILED;
74    }
75
76    releaseComplete = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.releaseComplete;
77    if(!releaseComplete)
78    {
79       OOTRACEWARN3("WARN: ReleaseComplete UUIE not found in received "
80                   "ReleaseComplete message - %s "
81                   "%s\n", call->callType, call->callToken);
82    }
83    else{
84
85       if(releaseComplete->m.reasonPresent)
86       {
87          OOTRACEINFO4("Release complete reason code %d. (%s, %s)\n", 
88                    releaseComplete->reason.t, call->callType, call->callToken);
89          reasonCode = releaseComplete->reason.t;
90       }
91    }
92
93    if(call->callEndReason == OO_REASON_UNKNOWN)
94       call->callEndReason = ooGetCallClearReasonFromCauseAndReasonCode(cause, 
95                                                                    reasonCode);
96 #if 0
97    if (q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
98        q931Msg->userInfo->h323_uu_pdu.h245Tunneling          &&
99        OO_TESTFLAG (call->flags, OO_M_TUNNELING) )
100    {
101       OOTRACEDBGB3("Handling tunneled messages in ReleaseComplete. (%s, %s)\n",
102                    call->callType, call->callToken);
103       ret = ooHandleTunneledH245Messages
104                     (call, &q931Msg->userInfo->h323_uu_pdu);
105       OOTRACEDBGB3("Finished handling tunneled messages in ReleaseComplete."
106                    " (%s, %s)\n", call->callType, call->callToken);
107    }
108 #endif
109    if(call->h245SessionState != OO_H245SESSION_IDLE && 
110       call->h245SessionState != OO_H245SESSION_CLOSED)
111    {
112       ooCloseH245Connection(call);
113    }
114
115    if(call->callState != OO_CALL_CLEAR_RELEASESENT)
116    {
117       if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
118       {
119          if(gH323ep.gkClient->state == GkClientRegistered){
120             OOTRACEDBGA3("Sending DRQ after received ReleaseComplete."
121                          "(%s, %s)\n", call->callType, call->callToken);
122             ooGkClientSendDisengageRequest(gH323ep.gkClient, call);
123          }
124       }
125    }
126    call->callState = OO_CALL_CLEARED;
127
128    return ret;
129 }
130
131 int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
132 {
133    H225Setup_UUIE *setup=NULL;
134    int i=0, ret=0;
135    H245OpenLogicalChannel* olc;
136    ASN1OCTET msgbuf[MAXMSGLEN];
137    H225TransportAddress_ipAddress_ip *ip = NULL;
138    Q931InformationElement* pDisplayIE=NULL;
139    OOAliases *pAlias=NULL;
140
141    call->callReference = q931Msg->callReference;
142  
143    if(!q931Msg->userInfo)
144    {
145       OOTRACEERR3("ERROR:No User-User IE in received SETUP message (%s, %s)\n",
146                   call->callType, call->callToken);
147       return OO_FAILED;
148    }
149    setup = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.setup;
150    if(!setup)
151    {
152       OOTRACEERR3("Error: Setup UUIE not found in received setup message - %s "
153                   "%s\n", call->callType, call->callToken);
154       return OO_FAILED;
155    }
156    memcpy(call->callIdentifier.guid.data, setup->callIdentifier.guid.data, 
157           setup->callIdentifier.guid.numocts);
158    call->callIdentifier.guid.numocts = setup->callIdentifier.guid.numocts;
159    
160    memcpy(call->confIdentifier.data, setup->conferenceID.data,
161           setup->conferenceID.numocts);
162    call->confIdentifier.numocts = setup->conferenceID.numocts;
163
164    /* check for display ie */
165    pDisplayIE = ooQ931GetIE(q931Msg, Q931DisplayIE);
166    if(pDisplayIE)
167    {
168       call->remoteDisplayName = (ASN1OCTET*) memAlloc(call->pctxt, 
169                                  pDisplayIE->length*sizeof(ASN1OCTET)+1);
170       strcpy(call->remoteDisplayName, pDisplayIE->data);
171    }
172    /*Extract Remote Aliases, if present*/
173    if(setup->m.sourceAddressPresent)
174    {
175       if(setup->sourceAddress.count>0)
176       {
177          ooH323RetrieveAliases(call, &setup->sourceAddress, 
178                                                        &call->remoteAliases);
179          pAlias = call->remoteAliases;
180          while(pAlias)
181          {
182             if(pAlias->type ==  T_H225AliasAddress_dialedDigits)
183             {
184               if(!call->callingPartyNumber)
185               {
186                  call->callingPartyNumber = (char*)memAlloc(call->pctxt,
187                                                     strlen(pAlias->value)*+1);
188                  if(call->callingPartyNumber)
189                  {
190                      strcpy(call->callingPartyNumber, pAlias->value);
191                  }
192               }
193               break;
194            }
195            pAlias = pAlias->next;
196          }
197       }
198    }
199    /* Extract, aliases used for us, if present. Also,
200       Populate calledPartyNumber from dialedDigits, if not yet populated using
201       calledPartyNumber Q931 IE. 
202    */      
203    if(setup->m.destinationAddressPresent)
204    {
205       if(setup->destinationAddress.count>0)
206       {
207          ooH323RetrieveAliases(call, &setup->destinationAddress, 
208                                                        &call->ourAliases);
209          pAlias = call->ourAliases;
210          while(pAlias)
211          {
212             if(pAlias->type == T_H225AliasAddress_dialedDigits)
213             {
214               if(!call->calledPartyNumber)
215               {
216                  call->calledPartyNumber = (char*)memAlloc(call->pctxt,
217                                                     strlen(pAlias->value)*+1);
218                  if(call->calledPartyNumber)
219                  {
220                     strcpy(call->calledPartyNumber, pAlias->value);
221                  }
222               }
223               break;
224             }
225             pAlias = pAlias->next; 
226          }
227       }
228    }
229
230    /* Check for tunneling */
231    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent)
232    {
233       /* Tunneling enabled only when tunneling is set to true and h245
234          address is absent. In the presence of H.245 address in received
235          SETUP message, tunneling is disabled, irrespective of tunneling
236          flag in the setup message*/
237       if(q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
238          !setup->m.h245AddressPresent)
239       {
240          if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
241          {
242             OO_SETFLAG (call->flags, OO_M_TUNNELING);
243             OOTRACEINFO3("Call has tunneling active (%s,%s)\n", call->callType,
244                           call->callToken);
245          }
246          else
247             OOTRACEINFO3("ERROR:Remote endpoint wants to use h245Tunneling, "
248                         "local endpoint has it disabled (%s,%s)\n",
249                         call->callType, call->callToken);
250       }
251       else {
252          if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
253          {
254             OOTRACEINFO3("Tunneling disabled by remote endpoint. (%s, %s)\n",
255                          call->callType, call->callToken);
256          }
257          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
258       }
259    }
260    else {
261       if(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
262       {
263          OOTRACEINFO3("Tunneling disabled by remote endpoint. (%s, %s)\n",
264                        call->callType, call->callToken);
265       }
266       OO_CLRFLAG (call->flags, OO_M_TUNNELING);
267    }
268    
269    /* Extract Remote IP address */
270    if(!setup->m.sourceCallSignalAddressPresent)
271    {
272       OOTRACEWARN3("WARNING:Missing source call signal address in received "
273                    "setup (%s, %s)\n", call->callType, call->callToken);
274    }
275    else{
276
277       if(setup->sourceCallSignalAddress.t != T_H225TransportAddress_ipAddress)
278       {
279          OOTRACEERR3("ERROR: Source call signalling address type not ip "
280                      "(%s, %s)\n", call->callType, call->callToken);
281          return OO_FAILED;
282       }
283
284       ip = &setup->sourceCallSignalAddress.u.ipAddress->ip;
285       sprintf(call->remoteIP, "%d.%d.%d.%d", ip->data[0], ip->data[1], 
286                                              ip->data[2], ip->data[3]);
287       call->remotePort =  setup->sourceCallSignalAddress.u.ipAddress->port;
288    }
289    
290    /* check for fast start */
291    
292    if(setup->m.fastStartPresent)
293    {
294       if(!OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART))
295       {
296          OOTRACEINFO3("Local endpoint does not support fastStart. Ignoring "
297                      "fastStart. (%s, %s)\n", call->callType, call->callToken);
298          OO_CLRFLAG (call->flags, OO_M_FASTSTART);
299       }
300       else if(setup->fastStart.n == 0)
301       {
302          OOTRACEINFO3("Empty faststart element received. Ignoring fast start. "
303                       "(%s, %s)\n", call->callType, call->callToken);
304          OO_CLRFLAG (call->flags, OO_M_FASTSTART);
305       }
306       else{
307          OO_SETFLAG (call->flags, OO_M_FASTSTART);
308          OOTRACEINFO3("FastStart enabled for call(%s, %s)\n", call->callType,
309                        call->callToken);
310       }
311    }
312
313    if (OO_TESTFLAG (call->flags, OO_M_FASTSTART))
314    {
315       /* For printing the decoded message to log, initialize handler. */
316       initializePrintHandler(&printHandler, "FastStart Elements");
317
318       /* Set print handler */
319       setEventHandler (call->pctxt, &printHandler);
320
321       for(i=0; i<(int)setup->fastStart.n; i++)
322       {
323          olc = NULL;
324          /*         memset(msgbuf, 0, sizeof(msgbuf));*/
325          olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
326                                               sizeof(H245OpenLogicalChannel));
327          if(!olc)
328          {
329             OOTRACEERR3("ERROR:Memory - ooOnReceivedSetup - olc (%s, %s)\n", 
330                         call->callType, call->callToken);
331             /*Mark call for clearing */
332             if(call->callState < OO_CALL_CLEAR)
333             {
334                call->callEndReason = OO_REASON_LOCAL_CLEARED;
335                call->callState = OO_CALL_CLEAR;
336             }
337             return OO_FAILED;
338          }
339          memset(olc, 0, sizeof(H245OpenLogicalChannel));
340          memcpy(msgbuf, setup->fastStart.elem[i].data, 
341                 setup->fastStart.elem[i].numocts);
342
343          setPERBuffer(call->pctxt, msgbuf, 
344                       setup->fastStart.elem[i].numocts, 1);
345          ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
346          if(ret != ASN_OK)
347          {
348             OOTRACEERR3("ERROR:Failed to decode fast start olc element "
349                         "(%s, %s)\n", call->callType, call->callToken);
350             /* Mark call for clearing */
351             if(call->callState < OO_CALL_CLEAR)
352             {
353                call->callEndReason = OO_REASON_INVALIDMESSAGE;
354                call->callState = OO_CALL_CLEAR;
355             }
356             return OO_FAILED;
357          }
358          /* For now, just add decoded fast start elemts to list. This list
359             will be processed at the time of sending CONNECT message. */
360          dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
361       }
362       finishPrint();
363       removeEventHandler(call->pctxt);
364    }
365
366    return OO_OK;
367 }
368
369
370
371 int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
372 {
373    H225CallProceeding_UUIE *callProceeding=NULL;
374    H245OpenLogicalChannel* olc;
375    ASN1OCTET msgbuf[MAXMSGLEN];
376    ooLogicalChannel * pChannel = NULL;
377    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
378    int i=0, ret=0;
379
380    if(!q931Msg->userInfo)
381    {
382       OOTRACEERR3("ERROR:No User-User IE in received CallProceeding message."
383                   " (%s, %s)\n", call->callType, call->callToken);
384       return OO_FAILED;
385    }
386    callProceeding = 
387              q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.callProceeding;
388    if(callProceeding == NULL)
389    {
390       OOTRACEERR3("Error: Received CallProceeding message does not have "
391                   "CallProceeding UUIE (%s, %s)\n", call->callType, 
392                   call->callToken);
393       /* Mark call for clearing */
394       if(call->callState < OO_CALL_CLEAR)
395       {
396          call->callEndReason = OO_REASON_INVALIDMESSAGE;
397          call->callState = OO_CALL_CLEAR;
398       }
399       return OO_FAILED;
400    }
401
402    /* Handle fast-start */
403    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART))
404    {
405       if(callProceeding->m.fastStartPresent)
406       {
407          /* For printing the decoded message to log, initialize handler. */
408          initializePrintHandler(&printHandler, "FastStart Elements");
409
410          /* Set print handler */
411          setEventHandler (call->pctxt, &printHandler);
412
413          for(i=0; i<(int)callProceeding->fastStart.n; i++)
414          {
415             olc = NULL;
416
417             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
418                                               sizeof(H245OpenLogicalChannel));
419             if(!olc)
420             {
421                OOTRACEERR3("ERROR:Memory - ooOnReceivedCallProceeding - olc"
422                            "(%s, %s)\n", call->callType, call->callToken);
423                /*Mark call for clearing */
424                if(call->callState < OO_CALL_CLEAR)
425                {
426                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
427                   call->callState = OO_CALL_CLEAR;
428                }
429                return OO_FAILED;
430             }
431             memset(olc, 0, sizeof(H245OpenLogicalChannel));
432             memcpy(msgbuf, callProceeding->fastStart.elem[i].data, 
433                                     callProceeding->fastStart.elem[i].numocts);
434             setPERBuffer(call->pctxt, msgbuf, 
435                          callProceeding->fastStart.elem[i].numocts, 1);
436             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
437             if(ret != ASN_OK)
438             {
439                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
440                            "(%s, %s)\n", call->callType, call->callToken);
441                /* Mark call for clearing */
442                if(call->callState < OO_CALL_CLEAR)
443                {
444                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
445                   call->callState = OO_CALL_CLEAR;
446                }
447                return OO_FAILED;
448             }
449
450             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
451
452             pChannel = ooFindLogicalChannelByOLC(call, olc);
453             if(!pChannel)
454             {
455                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
456                            "(%s, %s)\n",
457                             olc->forwardLogicalChannelNumber, call->callType, 
458                             call->callToken);
459                return OO_FAILED;
460             }
461             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
462             {
463                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
464                             "Number from %d to %d (%s, %s)\n", 
465                             pChannel->channelNo, 
466                             olc->forwardLogicalChannelNumber, call->callType, 
467                             call->callToken);
468                pChannel->channelNo = olc->forwardLogicalChannelNumber;
469             }
470             if(!strcmp(pChannel->dir, "transmit"))
471             {
472                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
473                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
474                {
475                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
476                               "channel %d (%s, %s)\n", 
477                               olc->forwardLogicalChannelNumber, call->callType,
478                               call->callToken);
479                   continue;
480                }
481             
482                /* Extract the remote media endpoint address */
483                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
484                if(!h2250lcp)
485                {
486                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
487                               "forward Logical Channel Parameters found. "
488                               "(%s, %s)\n", call->callType, call->callToken);
489                   return OO_FAILED;
490                }
491                if(!h2250lcp->m.mediaChannelPresent)
492                {
493                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
494                               "reverse media channel information found."
495                               "(%s, %s)\n", call->callType, call->callToken);
496                   return OO_FAILED;
497                }
498                ret = ooGetIpPortFromH245TransportAddress(call, 
499                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
500                                    &pChannel->remoteMediaPort);
501                
502                if(ret != OO_OK)
503                {
504                   OOTRACEERR3("ERROR:Unsupported media channel address type "
505                               "(%s, %s)\n", call->callType, call->callToken);
506                   return OO_FAILED;
507                }
508        
509                if(!pChannel->chanCap->startTransmitChannel)
510                {
511                   OOTRACEERR3("ERROR:No callback registered to start transmit "
512                               "channel (%s, %s)\n",call->callType, 
513                               call->callToken);
514                   return OO_FAILED;
515                }
516                pChannel->chanCap->startTransmitChannel(call, pChannel);
517             }
518             /* Mark the current channel as established and close all other 
519                logical channels with same session id and in same direction.
520             */
521             ooOnLogicalChannelEstablished(call, pChannel);
522          }
523          finishPrint();
524          removeEventHandler(call->pctxt);
525          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
526       }
527       
528    }
529
530    /* Retrieve the H.245 control channel address from the connect msg */
531    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
532       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
533       callProceeding->m.h245AddressPresent) {
534       OOTRACEINFO3("Tunneling and h245address provided."
535                    "Using Tunneling for H.245 messages (%s, %s)\n", 
536                    call->callType, call->callToken);
537    }
538    else if(callProceeding->m.h245AddressPresent)
539    {
540       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
541       {
542          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
543          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
544                       "provided in callProceeding message (%s, %s)\n", 
545                       call->callType, call->callToken);
546       }
547       ret = ooH323GetIpPortFromH225TransportAddress(call, 
548                                   &callProceeding->h245Address, call->remoteIP,
549                                   &call->remoteH245Port);
550       if(ret != OO_OK)
551       {
552          OOTRACEERR3("Error: Unknown H245 address type in received "
553                      "CallProceeding message (%s, %s)", call->callType, 
554                      call->callToken);
555          /* Mark call for clearing */
556          if(call->callState < OO_CALL_CLEAR)
557          {
558             call->callEndReason = OO_REASON_INVALIDMESSAGE;
559             call->callState = OO_CALL_CLEAR;
560          }
561          return OO_FAILED;
562       }
563    }
564    return OO_OK;
565 }
566
567
568 int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
569 {
570    H225Alerting_UUIE *alerting=NULL;
571    H245OpenLogicalChannel* olc;
572    ASN1OCTET msgbuf[MAXMSGLEN];
573    ooLogicalChannel * pChannel = NULL;
574    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
575    int i=0, ret=0;
576
577
578    if(!q931Msg->userInfo)
579    {
580       OOTRACEERR3("ERROR:No User-User IE in received Alerting message."
581                   " (%s, %s)\n", call->callType, call->callToken);
582       return OO_FAILED;
583    }
584    alerting = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.alerting;
585    if(alerting == NULL)
586    {
587       OOTRACEERR3("Error: Received Alerting message does not have "
588                   "alerting UUIE (%s, %s)\n", call->callType, 
589                   call->callToken);
590       /* Mark call for clearing */
591       if(call->callState < OO_CALL_CLEAR)
592       {
593          call->callEndReason = OO_REASON_INVALIDMESSAGE;
594          call->callState = OO_CALL_CLEAR;
595       }
596       return OO_FAILED;
597    }
598    /*Handle fast-start */
599    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) &&
600       !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
601    {
602       if(alerting->m.fastStartPresent)
603       {
604          /* For printing the decoded message to log, initialize handler. */
605          initializePrintHandler(&printHandler, "FastStart Elements");
606
607          /* Set print handler */
608          setEventHandler (call->pctxt, &printHandler);
609
610          for(i=0; i<(int)alerting->fastStart.n; i++)
611          {
612             olc = NULL;
613
614             olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
615                                               sizeof(H245OpenLogicalChannel));
616             if(!olc)
617             {
618                OOTRACEERR3("ERROR:Memory - ooOnReceivedAlerting - olc"
619                            "(%s, %s)\n", call->callType, call->callToken);
620                /*Mark call for clearing */
621                if(call->callState < OO_CALL_CLEAR)
622                {
623                   call->callEndReason = OO_REASON_LOCAL_CLEARED;
624                   call->callState = OO_CALL_CLEAR;
625                }
626                return OO_FAILED;
627             }
628             memset(olc, 0, sizeof(H245OpenLogicalChannel));
629             memcpy(msgbuf, alerting->fastStart.elem[i].data, 
630                                     alerting->fastStart.elem[i].numocts);
631             setPERBuffer(call->pctxt, msgbuf, 
632                          alerting->fastStart.elem[i].numocts, 1);
633             ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
634             if(ret != ASN_OK)
635             {
636                OOTRACEERR3("ERROR:Failed to decode fast start olc element "
637                            "(%s, %s)\n", call->callType, call->callToken);
638                /* Mark call for clearing */
639                if(call->callState < OO_CALL_CLEAR)
640                {
641                   call->callEndReason = OO_REASON_INVALIDMESSAGE;
642                   call->callState = OO_CALL_CLEAR;
643                }
644                return OO_FAILED;
645             }
646
647             dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
648
649             pChannel = ooFindLogicalChannelByOLC(call, olc);
650             if(!pChannel)
651             {
652                OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. "
653                            "(%s, %s)\n",
654                             olc->forwardLogicalChannelNumber, call->callType, 
655                             call->callToken);
656                return OO_FAILED;
657             }
658             if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
659             {
660                OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel"
661                             "Number from %d to %d (%s, %s)\n", 
662                             pChannel->channelNo, 
663                             olc->forwardLogicalChannelNumber, call->callType, 
664                             call->callToken);
665                pChannel->channelNo = olc->forwardLogicalChannelNumber;
666             }
667             if(!strcmp(pChannel->dir, "transmit"))
668             {
669                if(olc->forwardLogicalChannelParameters.multiplexParameters.t !=
670                   T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
671                {
672                   OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
673                               "channel %d (%s, %s)\n", 
674                               olc->forwardLogicalChannelNumber, call->callType,
675                               call->callToken);
676                   continue;
677                }
678             
679                /* Extract the remote media endpoint address */
680                h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
681                if(!h2250lcp)
682                {
683                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
684                               "forward Logical Channel Parameters found. "
685                               "(%s, %s)\n", call->callType, call->callToken);
686                   return OO_FAILED;
687                }
688                if(!h2250lcp->m.mediaChannelPresent)
689                {
690                   OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
691                               "reverse media channel information found."
692                               "(%s, %s)\n", call->callType, call->callToken);
693                   return OO_FAILED;
694                }
695                ret = ooGetIpPortFromH245TransportAddress(call, 
696                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
697                                    &pChannel->remoteMediaPort);
698                
699                if(ret != OO_OK)
700                {
701                   OOTRACEERR3("ERROR:Unsupported media channel address type "
702                               "(%s, %s)\n", call->callType, call->callToken);
703                   return OO_FAILED;
704                }
705        
706                if(!pChannel->chanCap->startTransmitChannel)
707                {
708                   OOTRACEERR3("ERROR:No callback registered to start transmit "
709                               "channel (%s, %s)\n",call->callType, 
710                               call->callToken);
711                   return OO_FAILED;
712                }
713                pChannel->chanCap->startTransmitChannel(call, pChannel);
714             }
715             /* Mark the current channel as established and close all other 
716                logical channels with same session id and in same direction.
717             */
718             ooOnLogicalChannelEstablished(call, pChannel);
719          }
720          finishPrint();
721          removeEventHandler(call->pctxt);
722          OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
723       }
724       
725    }
726
727    /* Retrieve the H.245 control channel address from the connect msg */
728    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
729       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
730       alerting->m.h245AddressPresent) {
731       OOTRACEINFO3("Tunneling and h245address provided."
732                    "Giving preference to Tunneling (%s, %s)\n", 
733                    call->callType, call->callToken);
734    }
735    else if(alerting->m.h245AddressPresent)
736    {
737       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
738       {
739          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
740          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
741                       "provided in Alerting message (%s, %s)\n", 
742                       call->callType, call->callToken);
743       }
744       ret = ooH323GetIpPortFromH225TransportAddress(call, 
745                                   &alerting->h245Address, call->remoteIP,
746                                   &call->remoteH245Port);
747       if(ret != OO_OK)
748       {
749          OOTRACEERR3("Error: Unknown H245 address type in received "
750                      "Alerting message (%s, %s)", call->callType, 
751                      call->callToken);
752          /* Mark call for clearing */
753          if(call->callState < OO_CALL_CLEAR)
754          {
755             call->callEndReason = OO_REASON_INVALIDMESSAGE;
756             call->callState = OO_CALL_CLEAR;
757          }
758          return OO_FAILED;
759       }
760    }
761    return OO_OK;
762 }
763    
764
765 int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
766 {
767    int ret, i;
768    H225Connect_UUIE *connect;
769    H245OpenLogicalChannel* olc;
770    ASN1OCTET msgbuf[MAXMSGLEN];
771    ooLogicalChannel * pChannel = NULL;
772    H245H2250LogicalChannelParameters * h2250lcp = NULL;  
773
774    if(!q931Msg->userInfo)
775    {
776       OOTRACEERR3("Error: UUIE not found in received H.225 Connect message"
777                   " (%s, %s)\n", call->callType, call->callToken);
778       /* Mark call for clearing */
779       if(call->callState < OO_CALL_CLEAR)
780       {
781          call->callEndReason = OO_REASON_INVALIDMESSAGE;
782          call->callState = OO_CALL_CLEAR;
783       }
784       return OO_FAILED;
785    }
786    /* Retrieve the connect message from the user-user IE & Q.931 header */
787    connect = q931Msg->userInfo->h323_uu_pdu.h323_message_body.u.connect;
788    if(connect == NULL)
789    {
790       OOTRACEERR3("Error: Received Connect message does not have Connect UUIE"
791                   " (%s, %s)\n", call->callType, call->callToken);
792       /* Mark call for clearing */
793       if(call->callState < OO_CALL_CLEAR)
794       {
795          call->callEndReason = OO_REASON_INVALIDMESSAGE;
796          call->callState = OO_CALL_CLEAR;
797       }
798       return OO_FAILED;
799    }
800
801    /*Handle fast-start */
802    if(OO_TESTFLAG (call->flags, OO_M_FASTSTART) && 
803       !OO_TESTFLAG (call->flags, OO_M_FASTSTARTANSWERED))
804    {
805       if(!connect->m.fastStartPresent)
806       {
807          OOTRACEINFO3("Remote endpoint has rejected fastStart. (%s, %s)\n",
808                       call->callType, call->callToken);
809          /* Clear all channels we might have created */
810          ooClearAllLogicalChannels(call);
811          OO_CLRFLAG (call->flags, OO_M_FASTSTART);
812       }
813    }
814
815    if (connect->m.fastStartPresent && 
816        !OO_TESTFLAG(call->flags, OO_M_FASTSTARTANSWERED))
817    {
818       /* For printing the decoded message to log, initialize handler. */
819       initializePrintHandler(&printHandler, "FastStart Elements");
820
821       /* Set print handler */
822       setEventHandler (call->pctxt, &printHandler);
823
824       for(i=0; i<(int)connect->fastStart.n; i++)
825       {
826          olc = NULL;
827          /* memset(msgbuf, 0, sizeof(msgbuf));*/
828          olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
829                                               sizeof(H245OpenLogicalChannel));
830          if(!olc)
831          {
832             OOTRACEERR3("ERROR:Memory - ooOnReceivedSignalConnect - olc"
833                         "(%s, %s)\n", call->callType, call->callToken);
834             /*Mark call for clearing */
835             if(call->callState < OO_CALL_CLEAR)
836             {
837                call->callEndReason = OO_REASON_LOCAL_CLEARED;
838                call->callState = OO_CALL_CLEAR;
839             }
840             finishPrint();
841             removeEventHandler(call->pctxt);
842             return OO_FAILED;
843          }
844          memset(olc, 0, sizeof(H245OpenLogicalChannel));
845          memcpy(msgbuf, connect->fastStart.elem[i].data, 
846                                            connect->fastStart.elem[i].numocts);
847          setPERBuffer(call->pctxt, msgbuf, 
848                       connect->fastStart.elem[i].numocts, 1);
849          ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
850          if(ret != ASN_OK)
851          {
852             OOTRACEERR3("ERROR:Failed to decode fast start olc element "
853                         "(%s, %s)\n", call->callType, call->callToken);
854             /* Mark call for clearing */
855             if(call->callState < OO_CALL_CLEAR)
856             {
857                call->callEndReason = OO_REASON_INVALIDMESSAGE;
858                call->callState = OO_CALL_CLEAR;
859             }
860             finishPrint();
861             removeEventHandler(call->pctxt);
862             return OO_FAILED;
863          }
864
865          dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc);
866
867          pChannel = ooFindLogicalChannelByOLC(call, olc);
868          if(!pChannel)
869          {
870             OOTRACEERR4("ERROR: Logical Channel %d not found, fasts start "
871                         "answered. (%s, %s)\n",
872                          olc->forwardLogicalChannelNumber, call->callType, 
873                          call->callToken);
874             finishPrint();
875             removeEventHandler(call->pctxt);
876             return OO_FAILED;
877          }
878          if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
879          {
880             OOTRACEINFO5("Remote endpoint changed forwardLogicalChannelNumber"
881                          "from %d to %d (%s, %s)\n", pChannel->channelNo,
882                           olc->forwardLogicalChannelNumber, call->callType, 
883                           call->callToken);
884             pChannel->channelNo = olc->forwardLogicalChannelNumber;
885          }
886          if(!strcmp(pChannel->dir, "transmit"))
887          {
888             if(olc->forwardLogicalChannelParameters.multiplexParameters.t != 
889                T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
890             {
891                OOTRACEERR4("ERROR:Unknown multiplex parameter type for channel"
892                            " %d (%s, %s)\n", olc->forwardLogicalChannelNumber, 
893                            call->callType, call->callToken);
894                continue;
895             }
896             
897             /* Extract the remote media endpoint address */
898             h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
899             if(!h2250lcp)
900             {
901                OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
902                            "forward Logical Channel Parameters found. (%s, %s)"
903                            "\n", call->callType, call->callToken);
904                finishPrint();
905                removeEventHandler(call->pctxt);
906                return OO_FAILED;
907             }
908             if(!h2250lcp->m.mediaChannelPresent)
909             {
910                OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
911                            "reverse media channel information found. (%s, %s)"
912                            "\n", call->callType, call->callToken);
913                finishPrint();
914                removeEventHandler(call->pctxt);
915                return OO_FAILED;
916             }
917
918             ret = ooGetIpPortFromH245TransportAddress(call, 
919                                    &h2250lcp->mediaChannel, pChannel->remoteIP,
920                                    &pChannel->remoteMediaPort);
921             if(ret != OO_OK)
922             {
923                OOTRACEERR3("ERROR:Unsupported media channel address type "
924                            "(%s, %s)\n", call->callType, call->callToken);
925                finishPrint();
926                removeEventHandler(call->pctxt);
927                return OO_FAILED;
928             }
929             if(!pChannel->chanCap->startTransmitChannel)
930             {
931                OOTRACEERR3("ERROR:No callback registered to start transmit "
932                          "channel (%s, %s)\n",call->callType, call->callToken);
933                finishPrint();
934                removeEventHandler(call->pctxt);
935                return OO_FAILED;
936             }
937             pChannel->chanCap->startTransmitChannel(call, pChannel);
938          }
939          /* Mark the current channel as established and close all other 
940             logical channels with same session id and in same direction.
941          */
942          ooOnLogicalChannelEstablished(call, pChannel);
943       }
944       finishPrint();
945       removeEventHandler(call->pctxt);
946       OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED);
947    }
948
949    /* Retrieve the H.245 control channel address from the CONNECT msg */
950    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent &&
951       q931Msg->userInfo->h323_uu_pdu.h245Tunneling &&
952       connect->m.h245AddressPresent) {
953       OOTRACEINFO3("Tunneling and h245address provided."
954                    "Giving preference to Tunneling (%s, %s)\n", 
955                    call->callType, call->callToken);
956    }
957    else if(connect->m.h245AddressPresent)
958    {
959       if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
960       {
961          OO_CLRFLAG (call->flags, OO_M_TUNNELING);
962          OOTRACEINFO3("Tunneling is disabled for call as H245 address is "
963                       "provided in connect message (%s, %s)\n", 
964                       call->callType, call->callToken);
965       }
966       ret = ooH323GetIpPortFromH225TransportAddress(call, 
967                  &connect->h245Address, call->remoteIP, &call->remoteH245Port);
968       if(ret != OO_OK)
969       {
970          OOTRACEERR3("Error: Unknown H245 address type in received Connect "
971                      "message (%s, %s)", call->callType, call->callToken);
972          /* Mark call for clearing */
973          if(call->callState < OO_CALL_CLEAR)
974          {
975             call->callEndReason = OO_REASON_INVALIDMESSAGE;
976             call->callState = OO_CALL_CLEAR;
977          }
978          return OO_FAILED;
979       }
980    }
981
982    if(call->remoteH245Port != 0)
983    {
984        /* Create an H.245 connection. 
985       */
986       if(ooCreateH245Connection(call)== OO_FAILED)
987       {
988          OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", 
989                      call->callType, call->callToken);
990
991          if(call->callState < OO_CALL_CLEAR)
992          {
993             call->callEndReason = OO_REASON_TRANSPORTFAILURE;
994             call->callState = OO_CALL_CLEAR;
995          }
996          return OO_FAILED;
997       }
998    }
999
1000    if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent)
1001    {
1002       if (!q931Msg->userInfo->h323_uu_pdu.h245Tunneling)
1003       {
1004          if (OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1005          {
1006             OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1007             OOTRACEINFO3("Tunneling is disabled by remote endpoint.(%s, %s)\n",
1008                           call->callType, call->callToken);
1009          }
1010       }
1011    }
1012    if (OO_TESTFLAG(call->flags, OO_M_TUNNELING))
1013    {
1014       OOTRACEDBGB3("Handling tunneled messages in CONNECT. (%s, %s)\n",
1015                     call->callType, call->callToken);
1016       ret = ooHandleTunneledH245Messages
1017          (call, &q931Msg->userInfo->h323_uu_pdu);
1018       OOTRACEDBGB3("Finished tunneled messages in Connect. (%s, %s)\n",
1019                     call->callType, call->callToken);
1020
1021       /*
1022         Send TCS as call established and no capability exchange has yet 
1023         started. This will be true only when separate h245 connection is not
1024         established and tunneling is being used.
1025       */
1026       if(call->localTermCapState == OO_LocalTermCapExchange_Idle)
1027       {
1028          /*Start terminal capability exchange and master slave determination */
1029          ret = ooSendTermCapMsg(call);
1030          if(ret != OO_OK)
1031          {
1032             OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n",
1033                          call->callType, call->callToken);
1034             return ret;
1035          }
1036       }
1037       if(call->masterSlaveState == OO_MasterSlave_Idle)
1038       {
1039          ret = ooSendMasterSlaveDetermination(call);
1040          if(ret != OO_OK)
1041          {
1042             OOTRACEERR3("ERROR:Sending Master-slave determination message "
1043                      "(%s, %s)\n", call->callType, call->callToken);
1044             return ret;
1045          }   
1046       }
1047
1048    }
1049    return OO_OK;  
1050 }
1051
1052 int ooHandleH2250Message(OOH323CallData *call, Q931Message *q931Msg)
1053 {
1054    int ret=OO_OK;
1055    ASN1UINT i;
1056    DListNode *pNode = NULL;
1057    OOTimer *pTimer=NULL;
1058    int type = q931Msg->messageType;
1059    switch(type)
1060    {
1061       case Q931SetupMsg: /* SETUP message is received */
1062          OOTRACEINFO3("Received SETUP message (%s, %s)\n", call->callType,
1063                        call->callToken);
1064          ooOnReceivedSetup(call, q931Msg);
1065
1066          /* H225 message callback */
1067          if(gH323ep.h225Callbacks.onReceivedSetup)
1068             gH323ep.h225Callbacks.onReceivedSetup(call, q931Msg);
1069
1070          /* Free up the mem used by the received message, as it's processing 
1071             is done. 
1072          */
1073          ooFreeQ931Message(q931Msg);
1074          
1075          ooSendCallProceeding(call);/* Send call proceeding message*/
1076          
1077          /* DISABLEGK is used to selectively disable gatekeeper use. For 
1078             incoming calls DISABLEGK can be set in onReceivedSetup callback by 
1079             application. Very useful in pbx applications where gk is used only 
1080             when call is to or from outside pbx domian
1081          */
1082          if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
1083          {
1084             if(gH323ep.gkClient->state == GkClientRegistered)
1085             {
1086                ret = ooGkClientSendAdmissionRequest(gH323ep.gkClient, call, 
1087                                                     FALSE);
1088                call->callState = OO_CALL_WAITING_ADMISSION;
1089             }
1090             else{
1091                /* TODO: Should send Release complete with reject reason */
1092                OOTRACEERR1("Error:Ignoring incoming call as not yet"
1093                            "registered with Gk\n");
1094             }
1095          }
1096          else {
1097             ret = ooH323CallAdmitted (call);
1098          }
1099          break;
1100
1101
1102       case Q931CallProceedingMsg: /* CALL PROCEEDING message is received */
1103          OOTRACEINFO3("H.225 Call Proceeding message received (%s, %s)\n",
1104                       call->callType, call->callToken);
1105          ooOnReceivedCallProceeding(call, q931Msg);
1106
1107          ooFreeQ931Message(q931Msg);
1108          break;
1109
1110
1111       case Q931AlertingMsg:/* ALERTING message received */
1112          OOTRACEINFO3("H.225 Alerting message received (%s, %s)\n", 
1113                       call->callType, call->callToken);
1114
1115          ooOnReceivedAlerting(call, q931Msg);
1116
1117          if(gH323ep.h323Callbacks.onAlerting && call->callState<OO_CALL_CLEAR)
1118             gH323ep.h323Callbacks.onAlerting(call);
1119          ooFreeQ931Message(q931Msg);
1120          break;
1121
1122
1123       case Q931ConnectMsg:/* CONNECT message received */
1124          OOTRACEINFO3("H.225 Connect message received (%s, %s)\n",
1125                       call->callType, call->callToken);
1126
1127          /* Disable call establishment timer */
1128          for(i = 0; i<call->timerList.count; i++)
1129          {
1130             pNode = dListFindByIndex(&call->timerList, i);
1131             pTimer = (OOTimer*)pNode->data;
1132             if(((ooTimerCallback*)pTimer->cbData)->timerType & 
1133                                                          OO_CALLESTB_TIMER)
1134             {
1135                memFreePtr(call->pctxt, pTimer->cbData);
1136                ooTimerDelete(call->pctxt, &call->timerList, pTimer);
1137                OOTRACEDBGC3("Deleted CallESTB timer. (%s, %s)\n", 
1138                                               call->callType, call->callToken);
1139                break;
1140             }
1141          }
1142          ret = ooOnReceivedSignalConnect(call, q931Msg);
1143          if(ret != OO_OK)
1144             OOTRACEERR3("Error:Invalid Connect message received. (%s, %s)\n",
1145                         call->callType, call->callToken);
1146          else{
1147              /* H225 message callback */
1148             if(gH323ep.h225Callbacks.onReceivedConnect)
1149                gH323ep.h225Callbacks.onReceivedConnect(call, q931Msg);
1150
1151             if(gH323ep.h323Callbacks.onCallEstablished)
1152                gH323ep.h323Callbacks.onCallEstablished(call);
1153          }
1154          ooFreeQ931Message(q931Msg);
1155          break;
1156       case Q931InformationMsg:
1157          OOTRACEINFO3("H.225 Information msg received (%s, %s)\n",
1158                        call->callType, call->callToken);
1159          ooFreeQ931Message(q931Msg);
1160          break;
1161
1162
1163       case Q931ReleaseCompleteMsg:/* RELEASE COMPLETE message received */
1164          OOTRACEINFO3("H.225 Release Complete message received (%s, %s)\n",
1165                       call->callType, call->callToken);
1166
1167          ooOnReceivedReleaseComplete(call, q931Msg);
1168          
1169          ooFreeQ931Message(q931Msg);
1170          break;
1171       case Q931FacilityMsg: 
1172          OOTRACEINFO3("H.225 Facility message Received (%s, %s)\n",
1173                        call->callType, call->callToken);
1174
1175          ooOnReceivedFacility(call, q931Msg); 
1176          ooFreeQ931Message(q931Msg);
1177          break;
1178       case Q931ProgressMsg:
1179          OOTRACEINFO3("H.225 Progress message received (%s, %s)\n",
1180                        call->callType, call->callToken);
1181          ooFreeQ931Message(q931Msg);
1182          break;
1183       case Q931StatusMsg:
1184          OOTRACEINFO3("H.225 Status message received (%s, %s)\n",
1185                        call->callType, call->callToken);
1186          ooFreeQ931Message(q931Msg);
1187          break;
1188       case Q931StatusEnquiryMsg:
1189          OOTRACEINFO3("H.225 Status Inquiry message Received (%s, %s)\n",
1190                        call->callType, call->callToken);
1191          ooFreeQ931Message(q931Msg);
1192          break;
1193       case Q931SetupAckMsg:
1194          OOTRACEINFO3("H.225 Setup Ack message received (%s, %s)\n",
1195                        call->callType, call->callToken);
1196          ooFreeQ931Message(q931Msg);
1197          break;
1198       case Q931NotifyMsg: 
1199          OOTRACEINFO3("H.225 Notify message Received (%s, %s)\n",
1200                        call->callType, call->callToken);
1201          ooFreeQ931Message(q931Msg);
1202          break;
1203       default:
1204          OOTRACEWARN3("Invalid H.225 message type received (%s, %s)\n",
1205                       call->callType, call->callToken);
1206          ooFreeQ931Message(q931Msg);
1207    }
1208    return ret;
1209 }
1210
1211 int ooOnReceivedFacility(OOH323CallData *call, Q931Message * pQ931Msg)
1212 {
1213    H225H323_UU_PDU * pH323UUPdu = NULL;
1214    H225Facility_UUIE * facility = NULL;
1215    int ret;
1216    H225TransportAddress_ipAddress_ip *ip = NULL;
1217    OOTRACEDBGC3("Received Facility Message.(%s, %s)\n", call->callType, 
1218                                                         call->callToken);
1219    /* Get Reference to H323_UU_PDU */
1220    if(!pQ931Msg->userInfo)
1221    {
1222       OOTRACEERR3("Error: UserInfo not found in received H.225 Facility "
1223                   "message (%s, %s)\n", call->callType, call->callToken);
1224       return OO_FAILED;
1225    }
1226    pH323UUPdu = &pQ931Msg->userInfo->h323_uu_pdu;
1227    if(!pH323UUPdu)
1228    {
1229       OOTRACEERR1("ERROR: H225H323_UU_PDU absent in incoming facility "
1230                   "message\n");
1231       return OO_FAILED;
1232    }
1233    facility = pH323UUPdu->h323_message_body.u.facility;
1234    if(facility)
1235    {
1236       /* Depending on the reason of facility message handle the message */
1237       if(facility->reason.t == T_H225FacilityReason_transportedInformation)
1238       {
1239          if(OO_TESTFLAG (call->flags, OO_M_TUNNELING))
1240          {
1241             OOTRACEDBGB3("Handling tunneled messages in Facility. (%s, %s)\n",
1242                call->callType, call->callToken);
1243             ooHandleTunneledH245Messages(call, pH323UUPdu);
1244             OOTRACEDBGB3("Finished handling tunneled messages in Facility."
1245                          "(%s, %s)\n",call->callType, call->callToken);
1246          }
1247          else
1248          {
1249             OOTRACEERR3("ERROR:Tunneled H.245 message received in facility. "
1250                         "Tunneling is disabled at local for this call (%s, %s)\n",
1251                         call->callType, call->callToken);
1252             return OO_FAILED;
1253          }
1254       }
1255       else if(facility->reason.t == T_H225FacilityReason_startH245)
1256       {
1257          OOTRACEINFO3("Remote wants to start a separate H.245 Channel "
1258                       "(%s, %s)\n", call->callType, call->callToken);
1259          /*start H.245 channel*/
1260          ret = ooHandleStartH245FacilityMessage(call, facility);
1261          if(ret != OO_OK)
1262          {
1263             OOTRACEERR3("ERROR: Handling startH245 facility message "
1264                         "(%s, %s)\n", call->callType, call->callToken);
1265             return ret;
1266          }
1267       }
1268       else if(facility->reason.t == T_H225FacilityReason_callForwarded)
1269       {
1270          OOTRACEINFO3("Call Forward Facility message received. (%s, %s)\n",
1271                       call->callType, call->callToken);
1272          if(!facility->m.alternativeAddressPresent && 
1273             !facility->m.alternativeAliasAddressPresent)
1274          {
1275             OOTRACEERR3("Error:No alternative address provided in call forward"
1276                        "facility message.(%s, %s)\n", call->callType, 
1277                         call->callToken);
1278             if(call->callState < OO_CALL_CLEAR)
1279             {
1280                call->callState = OO_CALL_CLEAR;
1281                call->callEndReason = OO_REASON_INVALIDMESSAGE;
1282             }
1283             return OO_OK;
1284          }
1285          call->pCallFwdData = (OOCallFwdData *) memAlloc(call->pctxt, 
1286                                                         sizeof(OOCallFwdData));
1287          if(!call->pCallFwdData)
1288          {
1289             OOTRACEERR3("Error:Memory - ooOnReceivedFacility - pCallFwdData "
1290                         "(%s, %s)\n", call->callType, call->callToken);
1291             return OO_FAILED;
1292          }
1293          call->pCallFwdData->fwdedByRemote = TRUE;
1294          call->pCallFwdData->ip[0]='\0';
1295          call->pCallFwdData->aliases = NULL;
1296          if(facility->m.alternativeAddressPresent)
1297          {
1298             if(facility->alternativeAddress.t != 
1299                                            T_H225TransportAddress_ipAddress)
1300             {
1301                OOTRACEERR3("ERROR: Source call signalling address type not ip "
1302                            "(%s, %s)\n", call->callType, call->callToken);
1303            
1304                return OO_FAILED;
1305             }
1306
1307             ip = &facility->alternativeAddress.u.ipAddress->ip;
1308             sprintf(call->pCallFwdData->ip, "%d.%d.%d.%d", ip->data[0], 
1309                                        ip->data[1], ip->data[2], ip->data[3]);
1310             call->pCallFwdData->port =  
1311                                facility->alternativeAddress.u.ipAddress->port;
1312          }
1313
1314          if(facility->m.alternativeAliasAddressPresent)
1315          {
1316             ooH323RetrieveAliases(call, &facility->alternativeAliasAddress, 
1317                                   &call->pCallFwdData->aliases);
1318          }
1319          /* Now we have to clear the current call and make a new call to
1320             fwded location*/
1321          if(call->callState < OO_CALL_CLEAR)
1322          {
1323             call->callState = OO_CALL_CLEAR;
1324             call->callEndReason = OO_REASON_REMOTE_FWDED;
1325          }
1326          else{
1327             OOTRACEERR3("Error:Can't forward call as it is being cleared."
1328                         " (%s, %s)\n", call->callType, call->callToken);
1329            return OO_OK;
1330          }
1331       }
1332       else{
1333          OOTRACEINFO3("Unhandled Facility reason type received (%s, %s)\n", 
1334                        call->callType, call->callToken);
1335       }
1336    }
1337    else{ /* Empty facility message Check for tunneling */
1338       OOTRACEDBGB3("Handling tunneled messages in empty Facility message."
1339                    " (%s, %s)\n", call->callType, call->callToken);
1340       ooHandleTunneledH245Messages(call, pH323UUPdu);
1341       OOTRACEDBGB3("Finished handling tunneled messages in empty Facility "
1342                    "message. (%s, %s)\n", call->callType, call->callToken);
1343    }
1344    
1345    return OO_OK;
1346 }
1347
1348 int ooHandleStartH245FacilityMessage
1349    (OOH323CallData *call, H225Facility_UUIE *facility)
1350 {
1351    H225TransportAddress_ipAddress *ipAddress = NULL;
1352    int ret;
1353    
1354    /* Extract H245 address */
1355    if(!facility->m.h245AddressPresent)
1356    {
1357       OOTRACEERR3("ERROR: startH245 facility message received with no h245 "
1358                   "address (%s, %s)\n", call->callType, call->callToken);
1359       return OO_FAILED;
1360    }
1361    if(facility->h245Address.t != T_H225TransportAddress_ipAddress)
1362    {
1363       OOTRACEERR3("ERROR:Unknown H245 address type in received startH245 "
1364                "facility message (%s, %s)\n", call->callType, call->callToken);
1365       return OO_FAILED;
1366    }
1367    ipAddress = facility->h245Address.u.ipAddress;
1368    if(!ipAddress)
1369    {
1370       OOTRACEERR3("ERROR:Invalid startH245 facility message. No H245 ip "
1371                   "address found. (%s, %s)\n", call->callType, call->callToken);
1372       return OO_FAILED;
1373    }
1374    
1375    sprintf(call->remoteIP, "%d.%d.%d.%d", ipAddress->ip.data[0],
1376                                           ipAddress->ip.data[1],
1377                                           ipAddress->ip.data[2],
1378                                           ipAddress->ip.data[3]);
1379    call->remoteH245Port = ipAddress->port;
1380
1381    /* disable tunneling for this call */
1382    OO_CLRFLAG (call->flags, OO_M_TUNNELING);
1383
1384    /*Establish an H.245 connection */
1385    ret = ooCreateH245Connection(call);
1386    if(ret != OO_OK)
1387    {
1388       OOTRACEERR3("ERROR: Failed to establish an H.245 connection with remote"
1389                   " endpoint (%s, %s)\n", call->callType, call->callToken);
1390       return ret;
1391    }
1392    return OO_OK;
1393 }
1394
1395 int ooHandleTunneledH245Messages
1396    (OOH323CallData *call, H225H323_UU_PDU * pH323UUPdu)
1397 {
1398    H245Message *pmsg;
1399    OOCTXT *pctxt = &gH323ep.msgctxt;
1400    int ret=0,i=0;
1401    
1402    OOTRACEDBGC3("Checking for tunneled H.245 messages (%s, %s)\n", 
1403                  call->callType, call->callToken);
1404
1405    /* Check whether there are tunneled messages */  
1406    if(pH323UUPdu->m.h245TunnelingPresent)
1407    {
1408       if(pH323UUPdu->h245Tunneling)
1409       {
1410          OOTRACEDBGB4("Total number of tunneled H245 messages are %d.(%s, %s)"
1411                       "\n", (int)pH323UUPdu->h245Control.n, call->callType, 
1412                       call->callToken);
1413          for(i=0; i< (int)pH323UUPdu->h245Control.n; i++)
1414          {
1415             OOTRACEDBGC5("Retrieving %d of %d tunneled H.245 messages."
1416                          "(%s, %s)\n",i+1, pH323UUPdu->h245Control.n,
1417                          call->callType, call->callToken);
1418             pmsg = (H245Message*)memAlloc(pctxt, sizeof(H245Message));
1419             if(!pmsg)
1420             {
1421                OOTRACEERR3("Error:Memory - ooHandleH245TunneledMessages - pmsg"
1422                           "(%s, %s)\n", call->callType, call->callToken);
1423                return OO_FAILED;
1424             }
1425
1426             setPERBuffer(pctxt, 
1427                          (ASN1OCTET*)pH323UUPdu->h245Control.elem[i].data,
1428                          pH323UUPdu->h245Control.elem[i].numocts, 1);  
1429
1430             initializePrintHandler(&printHandler, "Tunneled H.245 Message");
1431             memset(pmsg, 0, sizeof(H245Message));
1432             /* Set event handler */
1433             setEventHandler (pctxt, &printHandler);
1434             OOTRACEDBGC4("Decoding %d tunneled H245 message. (%s, %s)\n", 
1435                           i+1, call->callType, call->callToken);
1436             ret = asn1PD_H245MultimediaSystemControlMessage(pctxt, 
1437                                                             &(pmsg->h245Msg));
1438             if(ret != ASN_OK)
1439             {
1440                OOTRACEERR3("Error decoding H245 message (%s, %s)\n", 
1441                             call->callType, call->callToken);
1442                ooFreeH245Message(call,pmsg);
1443                return OO_FAILED;
1444             }
1445             finishPrint();
1446             removeEventHandler (pctxt);
1447             ooHandleH245Message(call, pmsg);
1448             memFreePtr(pctxt, pmsg);
1449             pmsg = NULL;
1450          }/* End of For loop */
1451       }/* End of if(h245Tunneling) */
1452    }
1453    return OO_OK;
1454 }
1455
1456 int ooH323RetrieveAliases
1457    (OOH323CallData *call, H225_SeqOfH225AliasAddress *pAddresses, 
1458     OOAliases **aliasList)
1459 {
1460    int i=0,j=0,k=0;
1461    DListNode* pNode=NULL;
1462    H225AliasAddress *pAliasAddress=NULL;
1463    OOAliases *newAlias=NULL;
1464    H225TransportAddress *pTransportAddrss=NULL;
1465
1466    if(!pAddresses)
1467    {
1468       OOTRACEWARN3("Warn:No Aliases present (%s, %s)\n", call->callType, 
1469                     call->callToken);
1470       return OO_OK;
1471    }
1472    /* check for aliases */
1473    if(pAddresses->count<=0)
1474       return OO_OK;
1475    
1476    for(i=0; i<(int)pAddresses->count; i++)
1477    {
1478       pNode = dListFindByIndex (pAddresses, i);
1479
1480       if(!pNode)
1481          continue;
1482
1483       pAliasAddress = (H225AliasAddress*)pNode->data;
1484
1485       if(!pAliasAddress)
1486          continue;
1487
1488       newAlias = (OOAliases*)memAlloc(call->pctxt, sizeof(OOAliases));
1489       if(!newAlias)
1490       {
1491          OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - newAlias "
1492                      "(%s, %s)\n", call->callType, call->callToken);
1493          return OO_FAILED;
1494       }
1495       memset(newAlias, 0, sizeof(OOAliases));
1496       switch(pAliasAddress->t)
1497       {
1498       case T_H225AliasAddress_dialedDigits:
1499          newAlias->type = T_H225AliasAddress_dialedDigits;
1500          newAlias->value = (char*) memAlloc(call->pctxt, 
1501                          strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
1502          if(!newAlias->value)
1503          {
1504             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
1505                         "newAlias->value(dialedDigits) (%s, %s)\n", 
1506                          call->callType, call->callToken);
1507             memFreePtr(call->pctxt, newAlias);  
1508             return OO_FAILED;
1509          }
1510
1511          memcpy(newAlias->value, pAliasAddress->u.dialedDigits,
1512                            strlen(pAliasAddress->u.dialedDigits)*sizeof(char));
1513          newAlias->value[strlen(pAliasAddress->u.dialedDigits)*sizeof(char)]='\0';
1514          break;
1515       case T_H225AliasAddress_h323_ID:
1516          newAlias->type = T_H225AliasAddress_h323_ID;
1517          newAlias->value = (char*)memAlloc(call->pctxt, 
1518                          (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
1519          if(!newAlias->value)
1520          {
1521             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
1522                         "newAlias->value(h323id) (%s, %s)\n", call->callType, 
1523                          call->callToken);
1524             memFreePtr(call->pctxt, newAlias);  
1525             return OO_FAILED;
1526          }
1527
1528          for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
1529          {
1530             if(pAliasAddress->u.h323_ID.data[j] < 256)
1531             {
1532                newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
1533             }
1534          }
1535          newAlias->value[k] = '\0';
1536          break;   
1537       case T_H225AliasAddress_url_ID:
1538          newAlias->type = T_H225AliasAddress_url_ID;
1539          newAlias->value = (char*)memAlloc(call->pctxt,
1540                               strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
1541          if(!newAlias->value)
1542          {
1543             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
1544                         "newAlias->value(urlid) (%s, %s)\n", call->callType, 
1545                          call->callToken);
1546             memFreePtr(call->pctxt, newAlias);  
1547             return OO_FAILED;
1548          }
1549
1550          memcpy(newAlias->value, pAliasAddress->u.url_ID,
1551                                strlen(pAliasAddress->u.url_ID)*sizeof(char));
1552          newAlias->value[strlen(pAliasAddress->u.url_ID)*sizeof(char)]='\0';
1553          break;
1554       case T_H225AliasAddress_transportID:
1555          newAlias->type = T_H225AliasAddress_transportID;
1556          pTransportAddrss = pAliasAddress->u.transportID;
1557          if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
1558          {
1559             OOTRACEERR3("Error:Alias transportID not an IP address"
1560                         "(%s, %s)\n", call->callType, call->callToken);
1561             memFreePtr(call->pctxt, newAlias);
1562             break;
1563          }
1564          /* hopefully ip:port value can't exceed more than 30 
1565             characters */
1566          newAlias->value = (char*)memAlloc(call->pctxt, 
1567                                                       30*sizeof(char));
1568          sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
1569                                   pTransportAddrss->u.ipAddress->ip.data[0],
1570                                   pTransportAddrss->u.ipAddress->ip.data[1],
1571                                   pTransportAddrss->u.ipAddress->ip.data[2],
1572                                   pTransportAddrss->u.ipAddress->ip.data[3],
1573                                   pTransportAddrss->u.ipAddress->port);
1574          break;
1575       case T_H225AliasAddress_email_ID:
1576          newAlias->type = T_H225AliasAddress_email_ID;
1577          newAlias->value = (char*)memAlloc(call->pctxt, 
1578                              strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
1579          if(!newAlias->value)
1580          {
1581             OOTRACEERR3("ERROR:Memory - ooH323RetrieveAliases - "
1582                         "newAlias->value(emailid) (%s, %s)\n", call->callType, 
1583                          call->callToken);
1584             memFreePtr(call->pctxt, newAlias);  
1585             return OO_FAILED;
1586          }
1587
1588          memcpy(newAlias->value, pAliasAddress->u.email_ID,
1589                               strlen(pAliasAddress->u.email_ID)*sizeof(char));
1590          newAlias->value[strlen(pAliasAddress->u.email_ID)*sizeof(char)]='\0';
1591          break;
1592       default:
1593          OOTRACEERR3("Error:Unhandled Alias type (%s, %s)\n", 
1594                        call->callType, call->callToken);
1595          memFreePtr(call->pctxt, newAlias);
1596          continue;
1597       }
1598
1599       newAlias->next = *aliasList;
1600       *aliasList = newAlias;
1601
1602       newAlias = NULL;
1603      
1604      pAliasAddress = NULL;
1605      pNode = NULL;
1606    }/* endof: for */
1607    return OO_OK;
1608 }
1609
1610
1611 int ooPopulateAliasList(OOCTXT *pctxt, OOAliases *pAliases,
1612                            H225_SeqOfH225AliasAddress *pAliasList )
1613 {
1614    H225AliasAddress *pAliasEntry=NULL;
1615    OOAliases * pAlias=NULL;
1616    ASN1BOOL bValid=FALSE;
1617    int i = 0;
1618
1619    dListInit(pAliasList);
1620    if(pAliases)
1621    {
1622       pAlias = pAliases;
1623       while(pAlias)
1624       {
1625          pAliasEntry = (H225AliasAddress*)memAlloc(pctxt, 
1626                                                      sizeof(H225AliasAddress));
1627          if(!pAliasEntry)
1628          {
1629             OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - pAliasEntry\n");
1630             return OO_FAILED;
1631          }
1632          switch(pAlias->type)
1633          {
1634          case T_H225AliasAddress_dialedDigits:
1635             pAliasEntry->t = T_H225AliasAddress_dialedDigits;
1636             pAliasEntry->u.dialedDigits = (ASN1IA5String)memAlloc(pctxt,
1637                                                      strlen(pAlias->value)+1);
1638             if(!pAliasEntry->u.dialedDigits)
1639             {
1640                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - "
1641                            "dialedDigits\n");
1642                memFreePtr(pctxt, pAliasEntry);
1643                return OO_FAILED;
1644             }
1645             strcpy((char*)pAliasEntry->u.dialedDigits, pAlias->value);
1646             bValid = TRUE;
1647             break;
1648          case T_H225AliasAddress_h323_ID:
1649             pAliasEntry->t = T_H225AliasAddress_h323_ID;
1650             pAliasEntry->u.h323_ID.nchars = strlen(pAlias->value);
1651             pAliasEntry->u.h323_ID.data = (ASN116BITCHAR*)memAllocZ
1652                      (pctxt, strlen(pAlias->value)*sizeof(ASN116BITCHAR));
1653             
1654             if(!pAliasEntry->u.h323_ID.data)
1655             {
1656                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - h323_id\n");
1657                memFreePtr(pctxt, pAliasEntry);
1658                return OO_FAILED;
1659             }
1660             for(i=0; *(pAlias->value+i) != '\0'; i++)
1661                pAliasEntry->u.h323_ID.data[i] =(ASN116BITCHAR)pAlias->value[i];
1662             bValid = TRUE;
1663             break;
1664          case T_H225AliasAddress_url_ID:
1665             pAliasEntry->t = T_H225AliasAddress_url_ID;
1666             pAliasEntry->u.url_ID = (ASN1IA5String)memAlloc(pctxt, 
1667                                                      strlen(pAlias->value)+1);
1668             if(!pAliasEntry->u.url_ID)
1669             {
1670                OOTRACEERR1("ERROR:Memory - ooPopulateAliasList - url_id\n");
1671                memFreePtr(pctxt, pAliasEntry);               
1672                return OO_FAILED;
1673             }
1674             strcpy((char*)pAliasEntry->u.url_ID, pAlias->value);
1675             bValid = TRUE;
1676             break;
1677          case T_H225AliasAddress_email_ID:
1678             pAliasEntry->t = T_H225AliasAddress_email_ID;
1679             pAliasEntry->u.email_ID = (ASN1IA5String)memAlloc(pctxt, 
1680                                                      strlen(pAlias->value)+1);
1681             if(!pAliasEntry->u.email_ID)
1682             {
1683                OOTRACEERR1("ERROR: Failed to allocate memory for EmailID "
1684                            "alias entry \n");
1685                return OO_FAILED;
1686             }
1687             strcpy((char*)pAliasEntry->u.email_ID, pAlias->value);
1688             bValid = TRUE;
1689             break;
1690          default:
1691             OOTRACEERR1("ERROR: Unhandled alias type\n");
1692             bValid = FALSE;                  
1693          }
1694          
1695          if(bValid)
1696             dListAppend( pctxt, pAliasList, (void*)pAliasEntry );
1697          else
1698             memFreePtr(pctxt, pAliasEntry);
1699          
1700          pAlias = pAlias->next;
1701       }
1702    }
1703    return OO_OK;
1704 }
1705
1706
1707 OOAliases* ooH323GetAliasFromList(OOAliases *aliasList, int type, char *value)
1708 {
1709
1710    OOAliases *pAlias = NULL;
1711
1712    if(!aliasList)
1713    {
1714       OOTRACEDBGC1("No alias List to search\n");
1715       return NULL;
1716    }
1717
1718    pAlias = aliasList;
1719
1720    while(pAlias)
1721    {
1722      if(type != 0 && value) { /* Search by type and value */
1723          if(pAlias->type == type && !strcmp(pAlias->value, value))
1724          {
1725             return pAlias;
1726          }
1727       }
1728       else if(type != 0 && !value) {/* search by type */
1729          if(pAlias->type == type)
1730             return pAlias;
1731       }
1732       else if(type == 0 && value) {/* search by value */
1733          if(!strcmp(pAlias->value, value))
1734             return pAlias;
1735       }
1736       else {
1737          OOTRACEDBGC1("No criteria to search the alias list\n");
1738          return NULL;
1739       }
1740       pAlias = pAlias->next;
1741    }
1742
1743    return NULL;
1744 }
1745
1746 OOAliases* ooH323AddAliasToList
1747 (OOAliases **pAliasList, OOCTXT *pctxt, H225AliasAddress *pAliasAddress)
1748 {
1749    int j=0,k=0;
1750    OOAliases *newAlias=NULL;
1751    H225TransportAddress *pTransportAddrss=NULL;
1752    
1753    newAlias = (OOAliases*) memAlloc(pctxt, sizeof(OOAliases));
1754    if(!newAlias)
1755    {
1756       OOTRACEERR1("Error: Failed to allocate memory for new alias to be added to the alias list\n");
1757       return NULL;
1758    }
1759    memset(newAlias, 0, sizeof(OOAliases));
1760
1761    switch(pAliasAddress->t)
1762    {
1763    case T_H225AliasAddress_dialedDigits:
1764       newAlias->type = T_H225AliasAddress_dialedDigits;
1765       newAlias->value = (char*) memAlloc(pctxt, strlen(pAliasAddress->u.dialedDigits)*sizeof(char)+1);
1766       strcpy(newAlias->value, pAliasAddress->u.dialedDigits);
1767       break;
1768    case T_H225AliasAddress_h323_ID:
1769       newAlias->type = T_H225AliasAddress_h323_ID;
1770       newAlias->value = (char*)memAlloc(pctxt, 
1771                            (pAliasAddress->u.h323_ID.nchars+1)*sizeof(char)+1);
1772
1773       for(j=0, k=0; j<(int)pAliasAddress->u.h323_ID.nchars; j++)
1774       {
1775          if(pAliasAddress->u.h323_ID.data[j] < 256)
1776          {
1777             newAlias->value[k++] = (char) pAliasAddress->u.h323_ID.data[j];
1778          }
1779       }
1780       newAlias->value[k] = '\0';
1781       break;   
1782    case T_H225AliasAddress_url_ID:
1783       newAlias->type = T_H225AliasAddress_url_ID;
1784       newAlias->value = (char*)memAlloc(pctxt,
1785                             strlen(pAliasAddress->u.url_ID)*sizeof(char)+1);
1786
1787       strcpy(newAlias->value, pAliasAddress->u.url_ID);
1788       break;
1789    case T_H225AliasAddress_transportID:
1790       newAlias->type = T_H225AliasAddress_transportID;
1791       pTransportAddrss = pAliasAddress->u.transportID;
1792       if(pTransportAddrss->t != T_H225TransportAddress_ipAddress)
1793       {
1794          OOTRACEERR1("Error:Alias transportID not an IP address\n");
1795          memFreePtr(pctxt, newAlias);
1796          return NULL;
1797       }
1798       /* hopefully ip:port value can't exceed more than 30 
1799          characters */
1800       newAlias->value = (char*)memAlloc(pctxt, 
1801                                               30*sizeof(char));
1802       sprintf(newAlias->value, "%d.%d.%d.%d:%d", 
1803                                pTransportAddrss->u.ipAddress->ip.data[0],
1804                                pTransportAddrss->u.ipAddress->ip.data[1],
1805                                pTransportAddrss->u.ipAddress->ip.data[2],
1806                                pTransportAddrss->u.ipAddress->ip.data[3],
1807                                pTransportAddrss->u.ipAddress->port);
1808       break;
1809    case T_H225AliasAddress_email_ID:
1810       newAlias->type = T_H225AliasAddress_email_ID;
1811       newAlias->value = (char*)memAlloc(pctxt, 
1812                  strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);
1813
1814       strcpy(newAlias->value, pAliasAddress->u.email_ID);
1815       break;
1816    default:
1817       OOTRACEERR1("Error:Unhandled Alias type \n");
1818       memFreePtr(pctxt, newAlias);
1819       return NULL;
1820
1821    }
1822    newAlias->next = *pAliasList;
1823    *pAliasList= newAlias;
1824    return newAlias;
1825 }
1826
1827 int ooH323GetIpPortFromH225TransportAddress(struct OOH323CallData *call, 
1828    H225TransportAddress *h225Address, char *ip, int *port)
1829 {
1830    if(h225Address->t != T_H225TransportAddress_ipAddress)
1831    {
1832       OOTRACEERR3("Error: Unknown H225 address type. (%s, %s)", call->callType,
1833                    call->callToken);
1834       return OO_FAILED;
1835    }
1836    sprintf(ip, "%d.%d.%d.%d", 
1837               h225Address->u.ipAddress->ip.data[0], 
1838               h225Address->u.ipAddress->ip.data[1],
1839               h225Address->u.ipAddress->ip.data[2],
1840               h225Address->u.ipAddress->ip.data[3]);
1841    *port = h225Address->u.ipAddress->port;
1842    return OO_OK;
1843 }