Skip to content
Snippets Groups Projects
ooCalls.c 28.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * Copyright (C) 2004-2005 by Objective Systems, Inc.
     *
     * This software is furnished under an open source license and may be 
     * used and copied only in accordance with the terms of this license. 
     * The text of the license may generally be found in the root 
     * directory of this installation in the COPYING file.  It 
     * can also be viewed online at the following URL:
     *
     *   http://www.obj-sys.com/open/license.html
     *
     * Any redistributions of this file including modified versions must 
     * maintain this copyright notice.
     *
     *****************************************************************************/
    
    
    #include "asterisk.h"
    #include "asterisk/lock.h"
    
    #include "asterisk/utils.h"
    
    #include "ootrace.h"
    #include "ootypes.h"
    #include "ooCalls.h"
    #include "ooUtils.h"
    #include "ooports.h"
    #include "oochannels.h"
    #include "ooh245.h"
    #include "ooCapability.h"
    #include "ooGkClient.h"
    #include "ooh323ep.h"
    #include "ooCalls.h"
    
    
    /** Global endpoint structure */
    extern OOH323EndPoint gH323ep;
    
    extern ast_mutex_t callListLock;
    extern ast_mutex_t newCallLock;
    
    
    OOH323CallData* ooCreateCall(char* type, char*callToken)
    {
       OOH323CallData *call=NULL;
       OOCTXT *pctxt=NULL;
    
       OOCTXT *msgctxt=NULL;
    
    
       pctxt = newContext();
       if(!pctxt)
       {
          OOTRACEERR1("ERROR:Failed to create OOCTXT for new call\n");
          return NULL;
       }
    
       msgctxt = newContext();
       if(!msgctxt)
       {
          OOTRACEERR1("ERROR:Failed to create OOCTXT for new call\n");
          return NULL;
       }
       ast_mutex_lock(&newCallLock);
       /* call = (OOH323CallData*)memAlloc(&gH323ep.ctxt, sizeof(OOH323CallData));  */
    
       call = (OOH323CallData*)memAlloc(pctxt, sizeof(OOH323CallData));
    
       ast_mutex_unlock(&newCallLock);
    
       if(!call)
       {
          OOTRACEERR1("ERROR:Memory - ooCreateCall - call\n");
          return NULL;
       } 
    
       memset(call, 0, sizeof(OOH323CallData));
       ast_cond_init(&call->gkWait, NULL);
    
       ast_mutex_init(&call->GkLock);
    
       ast_mutex_init(&call->Lock);
    
       call->msgctxt = msgctxt;
    
       call->callMode = gH323ep.callMode;
       sprintf(call->callToken, "%s", callToken);
       sprintf(call->callType, "%s", type);
       call->callReference = 0;
       if(gH323ep.callerid) {
         strncpy(call->ourCallerId, gH323ep.callerid, sizeof(call->ourCallerId)-1);
         call->ourCallerId[sizeof(call->ourCallerId)-1] = '\0';
       }
       else {
          call->ourCallerId[0] = '\0';
       }
       
       memset(&call->callIdentifier, 0, sizeof(H225CallIdentifier));
       memset(&call->confIdentifier, 0, sizeof(H225ConferenceIdentifier));
    
       call->flags = 0;
       if (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
          OO_SETFLAG (call->flags, OO_M_TUNNELING);
    
       if(gH323ep.gkClient)
       {
          if(OO_TESTFLAG(gH323ep.flags, OO_M_GKROUTED))
          {
             OO_SETFLAG(call->flags, OO_M_GKROUTED);
          }
       }
    
       if (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART))
          OO_SETFLAG (call->flags, OO_M_FASTSTART);
    
       if (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN))
          OO_SETFLAG (call->flags, OO_M_MEDIAWAITFORCONN);
    
    
       call->fsSent = FALSE;
    
    // May 20090713. Fix it for Video session
    
       OO_SETFLAG(call->flags, OO_M_AUDIOSESSION);
    
       
       call->callState = OO_CALL_CREATED;
       call->callEndReason = OO_REASON_UNKNOWN;
       call->pCallFwdData = NULL;
    
       if(!strcmp(call->callType, "incoming"))
       {
          call->callingPartyNumber = NULL;
       }
       else{      
          if(ooUtilsIsStrEmpty(gH323ep.callingPartyNumber))
          {
             call->callingPartyNumber = NULL;
          }
          else{
             call->callingPartyNumber = (char*) memAlloc(call->pctxt, 
                                             strlen(gH323ep.callingPartyNumber)+1);
             if(call->callingPartyNumber)
             {
                strcpy(call->callingPartyNumber, gH323ep.callingPartyNumber);
             }
             else{
                OOTRACEERR3("Error:Memory - ooCreateCall - callingPartyNumber"
                            ".(%s, %s)\n", call->callType, call->callToken);
                freeContext(pctxt);
                return NULL;
             }
          }
       }
    
       call->calledPartyNumber = NULL;
       call->h245ConnectionAttempts = 0;
       call->h245SessionState = OO_H245SESSION_IDLE;
       call->dtmfmode = gH323ep.dtmfmode;
       call->mediaInfo = NULL;
       strcpy(call->localIP, gH323ep.signallingIP);
       call->pH225Channel = NULL;
       call->pH245Channel = NULL;
       call->h245listener = NULL;
       call->h245listenport = NULL;
       call->remoteIP[0] = '\0';
       call->remotePort = 0;
       call->remoteH245Port = 0;
       call->remoteDisplayName = NULL;
       call->remoteAliases = NULL;
       call->ourAliases = NULL;
       call->masterSlaveState = OO_MasterSlave_Idle;
       call->statusDeterminationNumber = 0;
       call->localTermCapState = OO_LocalTermCapExchange_Idle;
       call->remoteTermCapState = OO_RemoteTermCapExchange_Idle; 
       call->ourCaps = NULL;
       call->remoteCaps = NULL;
       call->jointCaps = NULL;
       dListInit(&call->remoteFastStartOLCs);
       call->remoteTermCapSeqNo =0;
       call->localTermCapSeqNo = 0;
       memcpy(&call->capPrefs, &gH323ep.capPrefs, sizeof(OOCapPrefs));    
       call->logicalChans = NULL;
       call->noOfLogicalChannels = 0;
       call->logicalChanNoBase = 1001;
       call->logicalChanNoMax = 1100;
       call->logicalChanNoCur = 1001;
       call->nextSessionID = 4; /* 1,2,3 are reserved for audio, video and data */
       dListInit(&call->timerList);
       call->msdRetries = 0;
       call->pFastStartRes = NULL;
       call->usrData = NULL;
    
       OOTRACEINFO3("Created a new call (%s, %s)\n", call->callType, 
                     call->callToken);
       /* Add new call to calllist */
       ooAddCallToList (call);
       if(gH323ep.h323Callbacks.onNewCallCreated)
         gH323ep.h323Callbacks.onNewCallCreated(call);
       return call;
    }
    
    int ooAddCallToList(OOH323CallData *call)
    {
    
       ast_mutex_lock(&callListLock);
    
    
       if(!gH323ep.callList)
       {
          gH323ep.callList = call;
          call->next = NULL;
          call->prev = NULL;
       }
       else{
          call->next = gH323ep.callList;
          call->prev = NULL;
          gH323ep.callList->prev = call;
          gH323ep.callList = call;
       }
    
    
       ast_mutex_unlock(&callListLock);
    
    
       return OO_OK;
    }
    
    
    int ooEndCall(OOH323CallData *call)
    {
       OOTRACEDBGA4("In ooEndCall call state is - %s (%s, %s)\n", 
                     ooGetCallStateText(call->callState), call->callType, 
                     call->callToken);
    
    
       if(call->callState == OO_CALL_REMOVED) {
          OOTRACEINFO2("Call already removed %s\n",
                        call->callToken);
         return OO_OK;
       }
    
    
       if (call->callIdentifier.guid.numocts == 0) call->callState = OO_CALL_CLEARED;
    
    
       if(!call->pH225Channel || call->pH225Channel->sock ==0)
       {
          call->callState = OO_CALL_CLEARED;
       }
    
    
       if(call->callState == OO_CALL_CLEARED || ((strcmp(call->callType, "incoming")) &&
         call->callState == OO_CALL_CLEAR_RELEASESENT))
    
          call->callState = OO_CALL_REMOVED;
    
          return OO_OK;
       }
    
       if(call->logicalChans)
       {
          OOTRACEINFO3("Clearing all logical channels. (%s, %s)\n", call->callType,
                        call->callToken);
          ooClearAllLogicalChannels(call);
       }
    
       if(!OO_TESTFLAG(call->flags, OO_M_ENDSESSION_BUILT))
       {
          if(call->h245SessionState == OO_H245SESSION_ACTIVE ||
             call->h245SessionState == OO_H245SESSION_ENDRECVD)
          {
             ooSendEndSessionCommand(call);
             OO_SETFLAG(call->flags, OO_M_ENDSESSION_BUILT);
          }
       }
    
    
    
       if(!OO_TESTFLAG(call->flags, OO_M_RELEASE_BUILT))   
    
         if(call->callState == OO_CALL_CLEAR || 
            call->callState == OO_CALL_CLEAR_RELEASERECVD)
         {
            ooSendReleaseComplete(call);
            OO_SETFLAG(call->flags, OO_M_RELEASE_BUILT);
         }
    
       }
          
       return OO_OK;
    }
    
    
    
    int ooRemoveCallFromList (OOH323CallData *call)
    {
    
       if(!call || !gH323ep.callList)
    
       ast_mutex_lock(&callListLock);
    
       OOTRACEINFO3("Removing call %lx: %s\n", call, call->callToken);
    
    
       if(call == gH323ep.callList)
       {
          if(!call->next)
             gH323ep.callList = NULL;
          else{
             call->next->prev = NULL;
             gH323ep.callList = call->next;
          }
       }
       else{
          call->prev->next = call->next;
          if(call->next)
             call->next->prev = call->prev;
       }
    
    
       ast_mutex_unlock(&callListLock);
    
    
       return OO_OK;
    }
    
    int ooCleanCall(OOH323CallData *call)
    {
       OOCTXT *pctxt;
    
       OOTRACEWARN4 ("Cleaning Call (%s, %s)- reason:%s\n", 
                     call->callType, call->callToken, 
                     ooGetReasonCodeText (call->callEndReason));
    
       /* First clean all the logical channels, if not already cleaned. */
       if(call->logicalChans)
          ooClearAllLogicalChannels(call);
    
       /* Close H.245 connection, if not already closed */
       if(call->h245SessionState != OO_H245SESSION_CLOSED)
          ooCloseH245Connection(call);
       else{
          if(call->pH245Channel && call->pH245Channel->outQueue.count > 0)
          {
             dListFreeAll(call->pctxt, &(call->pH245Channel->outQueue));
             memFreePtr(call->pctxt, call->pH245Channel);
          }
       }
    
       /* Close H.245 listener, if not already closed */
       if(call->h245listener)
       {
          ooCloseH245Listener(call);
       }
       
       /* Close H225 connection, if not already closed. */
       if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
       {
          ooCloseH225Connection(call);
       }
    
       /* Clean timers */
       if(call->timerList.count > 0)
       {
          dListFreeAll(call->pctxt, &(call->timerList));
       }
    
       if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
       {
          ooGkClientCleanCall(gH323ep.gkClient, call);
       }
    
       ooRemoveCallFromList (call);
       OOTRACEINFO3("Removed call (%s, %s) from list\n", call->callType, 
                     call->callToken);
    
       if(call->pCallFwdData && call->pCallFwdData->fwdedByRemote)
       {
    
          if(gH323ep.h323Callbacks.onCallForwarded)
             gH323ep.h323Callbacks.onCallForwarded(call);
    
          if(ooH323HandleCallFwdRequest(call)!= OO_OK)
          {
             OOTRACEERR3("Error:Failed to forward call (%s, %s)\n", call->callType,
                         call->callToken);
          }
       }
       else {
          if(gH323ep.h323Callbacks.onCallCleared)
             gH323ep.h323Callbacks.onCallCleared(call);
       }
    
    
       if (call->rtpMask) {
    	ast_mutex_lock(&call->rtpMask->lock);
    	call->rtpMask->inuse--;
    	ast_mutex_unlock(&call->rtpMask->lock);
    	if ((call->rtpMask->inuse) == 0) {
    		regfree(&call->rtpMask->regex);
    		ast_mutex_destroy(&call->rtpMask->lock);
    
       if ((pctxt = call->msgctxt) != NULL) {
       	freeContext(pctxt);
    
       	call->msgctxt = NULL;
       }
    
    /* May !!!! Fix it !! */
       /* free(pctxt); */
    
    
       return OO_OK;
    }
    
    
    int ooCallSetCallerId(OOH323CallData* call, const char* callerid)
    {
       if(!call || !callerid) return OO_FAILED;
       strncpy(call->ourCallerId, callerid, sizeof(call->ourCallerId)-1);
       call->ourCallerId[sizeof(call->ourCallerId)-1]='\0';
       return OO_OK;
    }
    
    int ooCallSetCallingPartyNumber(OOH323CallData *call, const char *number)
    {
       if(call->callingPartyNumber) 
          memFreePtr(call->pctxt, call->callingPartyNumber);
    
       call->callingPartyNumber = (char*) memAlloc(call->pctxt, strlen(number)+1);
       if(call->callingPartyNumber)
       {
         strcpy(call->callingPartyNumber, number);
       }
       else{
          OOTRACEERR3("Error:Memory - ooCallSetCallingPartyNumber - "
                      "callingPartyNumber.(%s, %s)\n", call->callType, 
                      call->callToken);
          return OO_FAILED;
       }
       /* Set dialed digits alias */
       /*   if(!strcmp(call->callType, "outgoing"))
       {
          ooCallAddAliasDialedDigits(call, number);
       }*/
       return OO_OK;
    }
    
    int ooCallGetCallingPartyNumber(OOH323CallData *call, char *buffer, int len)
    {
       if(call->callingPartyNumber)
       {
          if(len>(int)strlen(call->callingPartyNumber))
          {
             strcpy(buffer, call->callingPartyNumber);
             return OO_OK;
          }
       }
       
       return OO_FAILED;
    }
    
    
    int ooCallSetCalledPartyNumber(OOH323CallData *call, const char *number)
    {
       if(call->calledPartyNumber) 
          memFreePtr(call->pctxt, call->calledPartyNumber);
    
       call->calledPartyNumber = (char*) memAlloc(call->pctxt, strlen(number)+1);
       if(call->calledPartyNumber)
       {
         strcpy(call->calledPartyNumber, number);
       }
       else{
          OOTRACEERR3("Error:Memory - ooCallSetCalledPartyNumber - "
                      "calledPartyNumber.(%s, %s)\n", call->callType, 
                      call->callToken);
          return OO_FAILED;
       }
       return OO_OK;
    }
    
    int ooCallGetCalledPartyNumber(OOH323CallData *call, char *buffer, int len)
    {
       if(call->calledPartyNumber)
       {
          if(len>(int)strlen(call->calledPartyNumber))
          {
             strcpy(buffer, call->calledPartyNumber);
             return OO_OK;
          }
       }
       
       return OO_FAILED;
    }
    
    int ooCallClearAliases(OOH323CallData *call)
    {
       if(call->ourAliases)
          memFreePtr(call->pctxt, call->ourAliases);
       call->ourAliases = NULL;
       return OO_OK;
    }
    
    
    int ooCallAddAlias
       (OOH323CallData *call, int aliasType, const char *value, OOBOOL local)
    {
       ooAliases * psNewAlias=NULL;
       psNewAlias = (ooAliases*)memAlloc(call->pctxt, sizeof(ooAliases));
       if(!psNewAlias)
       {
          OOTRACEERR3("Error:Memory - ooCallAddAlias - psNewAlias"
                      "(%s, %s)\n", call->callType, call->callToken);
          return OO_FAILED;
       }
       psNewAlias->type = aliasType;
       psNewAlias->value = (char*) memAlloc(call->pctxt, strlen(value)+1);
       if(!psNewAlias->value)
       {
          OOTRACEERR3("Error:Memory - ooCallAddAlias - psNewAlias->value"
                      " (%s, %s)\n", call->callType, call->callToken);
          memFreePtr(call->pctxt, psNewAlias);
          return OO_FAILED;
       }
       strcpy(psNewAlias->value, value);
    
       if(local)
       {
          psNewAlias->next = call->ourAliases;
          call->ourAliases = psNewAlias;
       }
       else {
         psNewAlias->next = call->remoteAliases;
         call->remoteAliases = psNewAlias;
       }
    
       OOTRACEDBGC5("Added %s alias %s to call. (%s, %s)\n", 
                  local?"local":"remote", value, call->callType, call->callToken);
       return OO_OK;
    }
    
    int ooCallAddAliasH323ID(OOH323CallData *call, const char* h323id)
    {
       return ooCallAddAlias(call, T_H225AliasAddress_h323_ID, h323id, TRUE);
    }
    
    
    int ooCallAddAliasDialedDigits(OOH323CallData *call, const char* dialedDigits)
    {
       return ooCallAddAlias
                   (call, T_H225AliasAddress_dialedDigits, dialedDigits, TRUE);
    }
    
    
    int ooCallAddAliasEmailID(OOH323CallData *call, const char* email)
    {
       return ooCallAddAlias(call, T_H225AliasAddress_email_ID, email, TRUE);
    }
    
    
    int ooCallAddAliasURLID(OOH323CallData *call, const char* url)
    {
       return ooCallAddAlias(call, T_H225AliasAddress_url_ID, url, TRUE);
    } 
     
    
    int ooCallAddRemoteAliasH323ID(OOH323CallData *call, const char* h323id)
    {
       return ooCallAddAlias(call, T_H225AliasAddress_h323_ID, h323id, FALSE);
    }
    
    int ooCallAddRemoteAliasDialedDigits
       (OOH323CallData *call, const char* dialedDigits)
    {
       return ooCallAddAlias
                  (call, T_H225AliasAddress_dialedDigits, dialedDigits, FALSE);
    }
    
    
    
    /* Used to override global end point capabilities and add call specific 
       capabilities */
    
    
    int ooCallAddG726Capability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, OOBOOL silenceSuppression, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
                                    silenceSuppression, dir, startReceiveChannel, 
                                    startTransmitChannel, stopReceiveChannel, 
                                    stopTransmitChannel, FALSE);
    }
    int ooCallAddAMRNBCapability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, OOBOOL silenceSuppression, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
                                    silenceSuppression, dir, startReceiveChannel, 
                                    startTransmitChannel, stopReceiveChannel, 
                                    stopTransmitChannel, FALSE);
    }
    
    int ooCallAddSpeexCapability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, OOBOOL silenceSuppression, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
                                    silenceSuppression, dir, startReceiveChannel, 
                                    startTransmitChannel, stopReceiveChannel, 
                                    stopTransmitChannel, FALSE);
    }
    
    
    int ooCallAddG7231Capability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, OOBOOL silenceSuppression, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
                                    silenceSuppression, dir, startReceiveChannel, 
                                    startTransmitChannel, stopReceiveChannel, 
                                    stopTransmitChannel, FALSE);
    }
    
    
    
    int ooCallAddG729Capability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
                              dir, startReceiveChannel, startTransmitChannel, 
                              stopReceiveChannel, stopTransmitChannel, FALSE);
    }
    
    /*
    int ooCallAddG726Capability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
                              dir, startReceiveChannel, startTransmitChannel, 
                              stopReceiveChannel, stopTransmitChannel, FALSE);
    }
    */
    
    int ooCallAddG728Capability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
                              dir, startReceiveChannel, startTransmitChannel, 
                              stopReceiveChannel, stopTransmitChannel, FALSE);
    }
    
    int ooCallAddG711Capability(OOH323CallData *call, int cap, int txframes, 
                                int rxframes, int dir,
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
                                dir, startReceiveChannel, startTransmitChannel, 
                                stopReceiveChannel, stopTransmitChannel, FALSE);
    }
    
    int ooCallAddGSMCapability
       (OOH323CallData* call, int cap, ASN1USINT framesPerPkt, 
        OOBOOL comfortNoise, OOBOOL scrambled, int dir,
        cb_StartReceiveChannel startReceiveChannel,
        cb_StartTransmitChannel startTransmitChannel,
        cb_StopReceiveChannel stopReceiveChannel,
        cb_StopTransmitChannel stopTransmitChannel)
    {
       return ooCapabilityAddGSMCapability(call, cap, framesPerPkt, comfortNoise, 
                                         scrambled, dir, startReceiveChannel, 
                                         startTransmitChannel, stopReceiveChannel,
                                         stopTransmitChannel, FALSE);
    }
    
    
    int ooCallAddH263VideoCapability
       (OOH323CallData *call, int cap, unsigned sqcifMPI, unsigned qcifMPI, 
        unsigned cifMPI, unsigned cif4MPI, unsigned cif16MPI, unsigned maxBitRate, 
        int dir, cb_StartReceiveChannel startReceiveChannel,
        cb_StartTransmitChannel startTransmitChannel,
        cb_StopReceiveChannel stopReceiveChannel,
        cb_StopTransmitChannel stopTransmitChannel)
    {
    
       return ooCapabilityAddH263VideoCapability(call, sqcifMPI, qcifMPI, cifMPI,
                                         cif4MPI, cif16MPI, maxBitRate,dir,
                                         startReceiveChannel, startTransmitChannel,
                                         stopReceiveChannel, stopTransmitChannel, 
                                         FALSE);
    
    }
    
    int ooCallEnableDTMFRFC2833(OOH323CallData *call, int dynamicRTPPayloadType)
    {
       return ooCapabilityEnableDTMFRFC2833(call, dynamicRTPPayloadType);
    }
    
    int ooCallDisableDTMFRFC2833(OOH323CallData *call)
    {
      return ooCapabilityDisableDTMFRFC2833(call);
    }
    
    
    int ooCallEnableDTMFCISCO(OOH323CallData *call, int dynamicRTPPayloadType)
    {
       return ooCapabilityEnableDTMFCISCO(call, dynamicRTPPayloadType);
    }
    
    int ooCallDisableDTMFCISCO(OOH323CallData *call)
    {
      return ooCapabilityDisableDTMFCISCO(call);
    }
    
    
    
    int ooCallEnableDTMFH245Alphanumeric(OOH323CallData *call)
    {
       return ooCapabilityEnableDTMFH245Alphanumeric(call);
    }
    
    int ooCallDisableDTMFH245Alphanumeric(OOH323CallData *call)
    {
       return ooCapabilityDisableDTMFH245Alphanumeric(call);
    }
    
    int ooCallEnableDTMFH245Signal(OOH323CallData *call)
    {
       return ooCapabilityEnableDTMFH245Signal(call);
    }
    
    int ooCallDisableDTMFH245Signal(OOH323CallData *call)
    {
       return ooCapabilityDisableDTMFH245Signal(call);
    }
    
    int ooCallEnableDTMFQ931Keypad(OOH323CallData *call)
    {
       return ooCapabilityEnableDTMFQ931Keypad(call);
    }
    
    int ooCallDisableDTMFQ931Keypad(OOH323CallData *call)
    {
       return ooCapabilityDisableDTMFQ931Keypad(call);
    }
    
    
    
    OOH323CallData* ooFindCallByToken(const char *callToken)
    
    {
       OOH323CallData *call;
       if(!callToken)
       {
          OOTRACEERR1("ERROR:Invalid call token passed - ooFindCallByToken\n");
          return NULL;
       }
    
    
       ast_mutex_lock(&callListLock);
    
    
       if(!gH323ep.callList)
       {
          OOTRACEERR1("ERROR: Empty calllist - ooFindCallByToken failed\n");
    
          ast_mutex_unlock(&callListLock);
    
          return NULL;
       }
       call = gH323ep.callList;
       while(call)
       {
          if(!strcmp(call->callToken, callToken))
             break;
          else
             call = call->next;
       }
       
       if(!call)
       {
          OOTRACEERR2("ERROR:Call with token %s not found\n", callToken);
    
          ast_mutex_unlock(&callListLock);
    
    
       ast_mutex_unlock(&callListLock);
    
       OOTRACEINFO3("INFO: FinCall returned %lx for call: %s\n", call, callToken);
    
    
       return call;
    }
    
    
    
    /* Checks whether session with suplied ID and direction is already active*/
    ASN1BOOL ooIsSessionEstablished(OOH323CallData *call, int sessionID, char* dir)
    {
       OOLogicalChannel * temp = NULL;
       temp = call->logicalChans;
       while(temp)
       {
          if(temp->sessionID == sessionID              &&
             temp->state == OO_LOGICALCHAN_ESTABLISHED && 
             !strcmp(temp->dir, dir)                     )
             return TRUE;
          temp = temp->next;
       }
       return FALSE;
    }
    
    int ooAddMediaInfo(OOH323CallData *call, OOMediaInfo mediaInfo)
    {
       OOMediaInfo *newMediaInfo=NULL;
    
       if(!call)
       {
          OOTRACEERR3("Error:Invalid 'call' param for ooAddMediaInfo.(%s, %s)\n",
                       call->callType, call->callToken);
          return OO_FAILED;
       }
       newMediaInfo = (OOMediaInfo*) memAlloc(call->pctxt, sizeof(OOMediaInfo));
       if(!newMediaInfo)
       {
          OOTRACEERR3("Error:Memory - ooAddMediaInfo - newMediaInfo. "
                      "(%s, %s)\n", call->callType, call->callToken);
          return OO_FAILED;
       }
    
       memcpy (newMediaInfo, &mediaInfo, sizeof(OOMediaInfo));
    
       OOTRACEDBGC4("Configured mediainfo for cap %s (%s, %s)\n", 
                    ooGetCapTypeText(mediaInfo.cap),
                    call->callType, call->callToken);
       if(!call->mediaInfo) {
          newMediaInfo->next = NULL;
          call->mediaInfo = newMediaInfo;
       }
       else {
          newMediaInfo->next = call->mediaInfo;
          call->mediaInfo = newMediaInfo;
       }
       return OO_OK;
    }
    
    unsigned ooCallGenerateSessionID
       (OOH323CallData *call, OOCapType type, char *dir)
    {
       unsigned sessionID=0;
    
       if(type == OO_CAP_TYPE_AUDIO)
       {
          if(!ooGetLogicalChannel(call, 1, dir))
          {
             sessionID = 1;
          }
          else{
             if(call->masterSlaveState == OO_MasterSlave_Master)
                sessionID = call->nextSessionID++;
             else{
                OOTRACEDBGC4("Session id for %s channel of type audio has to be "
                            "provided by remote.(%s, %s)\n", dir, call->callType, 
                             call->callToken);
                sessionID = 0; /* Will be assigned by remote */
             }
          }
       }
    
       if(type == OO_CAP_TYPE_VIDEO)
       {
          if(!ooGetLogicalChannel(call, 2, dir))
          {
             sessionID = 2;
          }
          else{
             if(call->masterSlaveState == OO_MasterSlave_Master)
                sessionID = call->nextSessionID++;
             else{
                sessionID = 0; /* Will be assigned by remote */
                OOTRACEDBGC4("Session id for %s channel of type video has to be "
                            "provided by remote.(%s, %s)\n", dir, call->callType, 
                             call->callToken);
             }
          }
       }
    
       if(type == OO_CAP_TYPE_DATA)
       {
          if(!ooGetLogicalChannel(call, 3, dir))
          {
             sessionID = 3;
          }
          else{
             if(call->masterSlaveState == OO_MasterSlave_Master)
                sessionID = call->nextSessionID++;
             else{
                sessionID = 0; /* Will be assigned by remote */
                OOTRACEDBGC4("Session id for %s channel of type data has to be "
                            "provided by remote.(%s, %s)\n", dir, call->callType, 
                             call->callToken);
             }
          }
       }
    
       return sessionID;
    
    }
    
    
    int ooCallH245ConnectionRetryTimerExpired(void *data)
    {
       ooTimerCallback *cbData = (ooTimerCallback*) data;
       OOH323CallData *call = cbData->call;
    
       OOTRACEINFO3("H245 connection retry timer expired. (%s, %s)\n", 
                                                call->callType, call->callToken); 
       memFreePtr(call->pctxt, cbData);
    
       call->h245ConnectionAttempts++;
    
       ooCreateH245Connection(call);
    
       return OO_OK;
    }
    
    const char* ooGetReasonCodeText (OOUINT32 code)
    {
       static const char* reasonCodeText[] = {
          "OO_REASON_UNKNOWN", 
          "OO_REASON_INVALIDMESSAGE",
          "OO_REASON_TRANSPORTFAILURE", 
          "OO_REASON_NOROUTE",
          "OO_REASON_NOUSER",
          "OO_REASON_NOBW",
          "OO_REASON_GK_NOCALLEDUSER",
          "OO_REASON_GK_NOCALLERUSER",
          "OO_REASON_GK_NORESOURCES",
          "OO_REASON_GK_UNREACHABLE",
          "OO_REASON_GK_CLEARED",
          "OO_REASON_NOCOMMON_CAPABILITIES",
          "OO_REASON_REMOTE_FWDED",   
          "OO_REASON_LOCAL_FWDED",
          "OO_REASON_REMOTE_CLEARED", 
          "OO_REASON_LOCAL_CLEARED", 
          "OO_REASON_REMOTE_BUSY",
          "OO_REASON_LOCAL_BUSY",
          "OO_REASON_REMOTE_NOANSWER",
          "OO_REASON_LOCAL_NOTANSWERED",
          "OO_REASON_REMOTE_REJECTED",
          "OO_REASON_LOCAL_REJECTED",
          "OO_REASON_REMOTE_CONGESTED",
          "OO_REASON_LOCAL_CONGESTED"
       };
       return ooUtilsGetText (code, reasonCodeText, OONUMBEROF(reasonCodeText));
    }
    
    const char* ooGetCallStateText (OOCallState callState)
    {
       static const char* callStateText[] = {
          "OO_CALL_CREATED",
          "OO_CALL_WAITING_ADMISSION",
          "OO_CALL_CONNECTING",
          "OO_CALL_CONNECTED",
          "OO_CALL_PAUSED",
          "OO_CALL_CLEAR",
          "OO_CALL_CLEAR_RELEASERECVD",
          "OO_CALL_CLEAR_RELEASESENT",
          "OO_CALL_CLEARED"
       };
       return ooUtilsGetText (callState, callStateText, OONUMBEROF(callStateText));
    }