⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmcall.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************************
        Copyright (c) 2002 RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Ltd.. No part of this document may be reproduced in any
form whatsoever without written prior approval by RADVISION Ltd..

RADVISION Ltd. reserve the right to revise this publication and make
changes without obligation to notify any person of such revisions or
changes.
***********************************************************************/

#include "rvinternal.h"
#include "rvlog.h"
#include "rvhost.h"
#include "msg.h"
#include "cm.h"
#include "cmintr.h"
#include "cmictrl.h"
#include "cmcallcid.h"
#include "cmCall.h"
#include "cmcallobj.h"
#include "q931asn1.h"
#include "stkutils.h"
#include "cmdebprn.h"
#include "cmutils.h"
#include "cmCrossReference.h"
#include "cmQ931.h"
#include "cmiFastStart.h"
#include "cmAutoRasCall.h"
#include "cmAutoRasEP.h"
#include "cmparam.h"
#include "cmControl.h"
#include "pvaltreeStackApi.h"
#include "psyntreeStackApi.h"
#include "rvh323mibstats.h"
#include "prnutils.h"
#include "oidutils.h"

#ifdef __cplusplus
extern "C" {
#endif

extern RvBool autoRasIrrTimeout(IN void* context);
void enterCallInitState(IN callElem* call);
void enterCallSetupState(IN callElem* call);
void enterCallConnectedState(IN callElem* call);
void enterCallRingbackState(callElem*call);
void enterCallIdleState(IN callElem* call);
void notifyControlState(IN HCALL hsCall);
int  cmcReadyEvent(IN H245Control* ctrl);
int  callAnswer(callElem*call);

int cmCallStatusMsg2Struct(HPVT hVal,int handle,cmCallStatusMessage * callStatusMsg);


RvBool controlDiedTimerEventsHandler(void*context);



/************************************************************************
 * simulatedMessageH245
 * purpose: define if message was simulated (was not sent actually)
 * input  : ctrl  - Stack handle for the H245 call control
 * output : none
 * return : true if simulated
 *          false - otherwise
 ************************************************************************/
RvBool simulatedMessageH245(IN HCONTROL ctrl)
{
    callElem*call=(callElem*)cmiGetByControl(ctrl);
    HSTRANSSESSION   hsTransSession=call->hsTransSession;
    
	return dummyControlSession(hsTransSession);
}


/************************************************************************
 * sendMessage
 * purpose: Send TCP (Q931/H245) message for a given call.
 *          This function also adds specific call-related information
 * input  : hsCall  - Stack handle for the call
 *          vNodeId - root node ID of the message to send
 *          type    - Type of channel to send on
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int sendMessage(IN HCALL hsCall, IN RvPvtNodeId vNodeId, IN cmTpktChanHandleType type)
{
    callElem*call=(callElem*)hsCall;
    TRANSERR result;

    /* Message should be processed - send it out */
    result = cmTransSendMessage(call->hsTransSession, vNodeId, (type==cmQ931TpktChannel)?cmTransQ931Type:cmTransH245Type);
    if ((result == cmTransWouldBlock) || (result < 0))
        return RV_ERROR_UNKNOWN;
    return 0;
}

/************************************************************************
 * sendCallMessage
 * purpose: Send Q931 message for a given call.
 *          This function also adds specific call-related information
 * input  : hsCall  - Stack handle for the Q931 call
 *          message - root node ID of the message to send
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int sendCallMessage(IN HCALL hsCall, IN RvPvtNodeId message)
{
    cmElem* app = (cmElem *)emaGetInstance((EMAElement)hsCall);
    callElem*call=(callElem*)hsCall;
    int tmpNodeId;
    int msgNodeId,uuieId;
    HPVT hVal= app->hVal;

    /*Add to the message the identification parameters*/
    /*CRV*/
    __pvtBuildByFieldIds(tmpNodeId,hVal,message, {_q931(callReferenceValue) _q931(twoBytes) LAST_TOKEN},call->crv,NULL);

    __pvtGetNodeIdByFieldIds(uuieId,hVal,message, {_q931(message) _anyField _q931(userUser)
                                                   _q931(h323_UserInformation) _q931(h323_uu_pdu) LAST_TOKEN});
    __pvtGetNodeIdByFieldIds(msgNodeId,hVal,uuieId, {_q931(h323_message_body) _anyField LAST_TOKEN});
    /*Call ID*/
    __pvtBuildByFieldIds(tmpNodeId,hVal,msgNodeId, {_q931(callIdentifier) _q931(guid) LAST_TOKEN},16,(char*)call->callId);
    /*CID*/
    if (m_callget(call, overrideCID))
    {
        __pvtBuildByFieldIds(tmpNodeId,hVal,msgNodeId, {_q931(conferenceID) LAST_TOKEN},16,(char*)call->cId);
    }
    /*Add dest info field*/
    if (call->destinationInfo>=0)
        pvtSetTree(hVal,pvtAddBranch(hVal,msgNodeId, __q931(destinationInfo)),
               hVal,call->destinationInfo);

    /*Add fast start messages in*/
    addFastStart(call,message);

    /* Send the message on Q931 channel */
    return sendMessage(hsCall,message,cmQ931TpktChannel);
}

/************************************************************************
 * sendMessageH245
 * purpose: Send H245 message for a given call.
 * input  : ctrl  - Stack handle for the H245 call control
 *          message - root node ID of the message to send
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int sendMessageH245(IN HCONTROL ctrl, IN int message)
{
    callElem*call=(callElem*)cmiGetByControl(ctrl);
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)call);

    int nesting;
    if(((cmElem*)hApp)->cmMyCallEvent.cmEvCallSendMessage)
    {
        cmiCBEnter(hApp,(char*)"cmEvCallSendMessage(haCall=0x%p,hsCall=0x%p)",(HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
        nesting=emaPrepareForCallback((EMAElement)call);
        (((cmElem*)hApp)->cmMyCallEvent.cmEvCallSendMessage)((HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call, message);
        emaReturnFromCallback((EMAElement)call,nesting);
        cmiCBExit(hApp,(char*)"cmEvCallSendMessage");
    }

    return sendMessage(cmiGetByControl(ctrl),message,cmH245TpktChannel);
}

/************************************************************************
 * cmCallGetMessageContext
 * purpose: Get the message context for a given call. This function is
 *          used for checking security results of messages for a call.
 * input  : hsCall      - Stack handle for the call
 * output : hMsgContext - Message context for call (of the last message)
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
RVAPI
int RVCALLCONV cmCallGetMessageContext(
    IN  HCALL            hsCall,
    OUT void**           hMsgContext)
{
    callElem*call=(callElem*)hsCall;
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)call);

    cmiAPIEnter(hApp,(char*)"cmCallGetMessageContext: hsCall=0x%p",hsCall);

    if (emaLock((EMAElement)hsCall))
    {
        if (hMsgContext)
            *hMsgContext=call->hMsgContext;
        emaUnlock((EMAElement)hsCall);
    }
    cmiAPIExit(hApp,(char*)"cmCallGetMessageContext: [0]");

    return 0;
}


TRANSERR cmEvTransHostListen(
            IN HSTRANSHOST          hsTransHost,
            IN HATRANSHOST          haTransHost,
            IN TRANSCONNTYPE        type,
            IN cmTransportAddress   *address)
{
    HAPP hApp=(HAPP)cmTransGetHApp(hsTransHost);
    cmElem* app=(cmElem*)hApp;
    int addr;
    RvBool proceed=RV_TRUE;

    if (type || haTransHost);

    if (hsTransHost && hApp)
    {
        addr=pvtAddRoot(app->hVal,app->hAddrSyn,0,NULL);

        if (addr>=0 && address)
        {
            cmTAToVt(app->hVal,addr,address);

            if (app->cmMyProtocolEvent.hookListen!=NULL)
                proceed=!app->cmMyProtocolEvent.hookListen((HPROTCONN)hsTransHost,addr);

            pvtDelete(app->hVal,addr);
        }
    }
    return (proceed)?cmTransOK:cmTransIgnoreMessage;
}

TRANSERR cmEvTransHostListening(
            IN HSTRANSHOST          hsTransHost,
            IN HATRANSHOST          haTransHost,
            IN TRANSCONNTYPE        type,
            IN cmTransportAddress   *address,
            IN RvBool               error)
{
    HAPP hApp=(HAPP)cmTransGetHApp(hsTransHost);
    cmElem* app=(cmElem*)hApp;
    int addr;
    RvBool proceed=RV_TRUE;

    if (type || haTransHost);

    if (hsTransHost && hApp)
    {
        addr=pvtAddRoot(app->hVal,app->hAddrSyn,0,NULL);

        if (addr>=0 && address)
        {
            cmTAToVt(app->hVal,addr,address);

            if (app->cmMyProtocolEvent.hookListening!=NULL)
                proceed=!app->cmMyProtocolEvent.hookListening((HPROTCONN)hsTransHost,addr,error);

            pvtDelete(app->hVal,addr);
        }
    }
    return (proceed)?cmTransOK:cmTransIgnoreMessage;
}

TRANSERR cmEvTransHostConnecting(
            IN HSTRANSHOST          hsTransHost,
            IN HATRANSHOST          haTransHost,
            IN TRANSCONNTYPE        type,
            IN cmTransportAddress   *address)
{
    HAPP hApp=(HAPP)cmTransGetHApp(hsTransHost);
    cmElem* app=(cmElem*)hApp;
    int addr;
    RvBool proceed=RV_TRUE;

    if (type || haTransHost);

    /* See if we need this hook at all */
    if ((app->cmMyProtocolEvent.hookConnecting != NULL) && (address != NULL))
    {
        addr = pvtAddRoot(app->hVal,app->hAddrSyn,0,NULL);

        if (addr >= 0)
        {
            cmTAToVt(app->hVal, addr, address);

            /* See if we should proceed with this connection - it's up to the application */
            proceed = !app->cmMyProtocolEvent.hookConnecting((HPROTCONN)hsTransHost,addr);

            /* Get rid of this node - we only needed it for the hook */
            pvtDelete(app->hVal,addr);
        }
    }

    return (proceed)?cmTransOK:cmTransIgnoreMessage;
}


TRANSERR cmEvTransHostConnected(IN HSTRANSHOST   hsTransHost,
                                IN HATRANSHOST   haTransHost,
                                IN TRANSCONNTYPE type,
                                IN RvBool        isOutgoing)
{
    HAPP hApp=(HAPP)cmTransGetHApp(hsTransHost);
    cmElem* app=(cmElem*)hApp;
    cmTransportAddress ta;
    int addrRemote,addrLocal;

    if (type || haTransHost);

    /* Make sure application wants to deal with these hooks at all */
    if ((isOutgoing && (app->cmMyProtocolEvent.hookOutConn == NULL)) ||
        (!isOutgoing && (app->cmMyProtocolEvent.hookInConn == NULL)))
        return cmTransOK;

    addrRemote=pvtAddRoot(app->hVal,app->hAddrSyn,0,NULL);
    addrLocal=pvtAddRoot(app->hVal,app->hAddrSyn,0,NULL);
    if (addrRemote>=0 && addrLocal>=0)
    {
        if (cmTransGetHostParam(hsTransHost, cmTransHostParam_remoteAddress, (void*)&ta)==cmTransOK)
        {
            cmTAToVt(app->hVal,addrRemote,&ta);
            if (cmTransGetHostParam(hsTransHost, cmTransHostParam_localAddress, (void*)&ta)==cmTransOK)
                cmTAToVt(app->hVal,addrLocal,&ta);

            /* No need to check if hooks exist - we already did that at the beginning of this function */
            if (isOutgoing)
                app->cmMyProtocolEvent.hookOutConn((HPROTCONN)hsTransHost,addrLocal,addrRemote,RV_FALSE);
            else
                app->cmMyProtocolEvent.hookInConn((HPROTCONN)hsTransHost,addrRemote,addrLocal);
        }
    }
    pvtDelete(app->hVal,addrRemote);
    pvtDelete(app->hVal,addrLocal);
    return cmTransOK;
}


TRANSERR cmEvTransHostClosed(   IN HSTRANSHOST hsTransHost,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -