📄 cmcall.c
字号:
/***********************************************************************
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 + -