📄 cmcall.c
字号:
default:
break;
}
if (stateMode==cmCallStateModeDisconnectedNormal)
/*The state mode still not determined properly*/
{
switch(call->state)
{
case cmCallStateInit:
case cmCallStateDialtone:
stateMode=cmCallStateModeDisconnectedUnreachable;
break;
case cmCallStateProceeding:
case cmCallStateRingBack:
stateMode=cmCallStateModeDisconnectedReject;
break;
case cmCallStateTransfering:
case cmCallStateDisconnected:
case cmCallStateIdle:
/*If we in one of this states, then we already reported the disconnected state*/
doNotReport=RV_TRUE;
break;
default:
break;
}
}
if (!doNotReport)
notifyState((HCALL)call,state,stateMode);
}
}
/************************************************************************
* dropControl
* purpose: Drop the H245 Control connection for a call.
* This function is used when calls are disconnected
* input : call - Stack handle for the call
* output : none
* return : none
************************************************************************/
void dropControl(IN callElem* call)
{
HCONTROL hCtrl;
hCtrl = cmiGetControl((HCALL)call);
/* See if we have to stop the control at all */
if (m_callget(call, control))
{
/* First update the status so we don't get into stopControl() twice from 2 different
threads: one on the incoming endSessionCommand and one for an outgoing one */
m_callset(call, control, RV_FALSE);
stopControl(hCtrl);
}
/* Close all channels of this call */
closeChannels(hCtrl);
}
/************************************************************************
* dropRas
* purpose: Notify the gatekeeper the call was disconnected before finishing
* off with this call
* input : call - Stack handle for the call
* output : none
* return : none
************************************************************************/
void dropRas(callElem*call)
{
int ret = 0;
cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
if (!emaWasDeleted((EMAElement)call))
{
if (!app->manualRAS && !m_callget(call,dummyRAS))
{
/* Automatic RAS - send DRQ on call if necessary */
ret = cmiAutoRASCallDrop((HCALL)call);
}
if (app->manualRAS || m_callget(call,dummyRAS) || (ret < 0))
{
if (!app->manualRAS)
cmiAutoRASCallClose((HCALL)call);
/* Manual RAS - continue to drop the call */
callStopOK(call);
}
}
}
int callStartError(callElem*call)
{
dropControl(call);
reportDisconnectedState(call,reasonDRQ);
if (!m_callget(call,callInitiator))
q931CallDrop(cmiGetQ931((HCALL)call),-1);
/* If GK has rejected our call then just close the call*/
/* No RAS drop required*/
callStopOK(call);
return 0;
}
int callIncompleteAddress(callElem*call)
{
cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
if (m_callget(call,callInitiator))
{
if (m_callget(call,enableOverlapSending))
{
if (app->cmMyCallEvent.cmEvCallIncompleteAddress)
{
int nesting;
cmiCBEnter((HAPP)app,(char*)"cmEvCallIncompleteAddress(haCall=0x%p,hsCall=0x%p)",(HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
nesting=emaPrepareForCallback((EMAElement)call);
app->cmMyCallEvent.cmEvCallIncompleteAddress((HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
emaReturnFromCallback((EMAElement)call,nesting);
cmiCBExit((HAPP)app,(char*)"cmEvCallIncompleteAddress");
}
}
else
{
dropControl(call);
reportDisconnectedState(call,reasonDRQ);
if (!m_callget(call,callInitiator))
q931CallDrop(cmiGetQ931((HCALL)call),-1);
/* If GK has rejected our call then just close the call*/
/* No RAS drop required*/
callStopOK(call);
return RV_ERROR_NOTSUPPORTED;
}
}
return RV_OK;
}
int callStartRoute(callElem*call)
{
cmTransportAddress ta;
if (!m_callget(call,callInitiator))
{
cmCallSetParam((HCALL)call,cmParamFacilityReason,0,cmReasonTypeRouteCallToGatekeeper,NULL);
cmGetGKCallSignalAddress((HAPP)emaGetInstance((EMAElement)call),&ta);
cmCallSetParam((HCALL)call,cmParamAlternativeAddress,0,0,(char*)&ta);
q931CallFacility(cmiGetQ931((HCALL)call),-1);
}
else
callStartError(call);
return 0;
}
/************************************************************************
* callDial
* purpose: Dials a call or answers incoming Setup requests.
* This function checks if we have to ARQ the GK on this call or
* not and continues the call setup process.
* input : call - Stack handle for the call to dial
* output : none
* return : negative on error
************************************************************************/
static int callDial(IN callElem* call)
{
cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
cmTransportAddress ta;
m_callset(call,dummyRAS,RV_FALSE);
if (app->manualRAS)
m_callset(call,dummyRAS,RV_TRUE);
else
{
if (call->preGrantedArqUse>=0)
{
/* PreGrantedARQ is used */
if (m_callget(call,callInitiator))
{
/* Let's see if we've got a PreGranted call making on this outgoing call */
if (app->rasGranted&makeCall)
{
if ( !(app->rasGranted&useGKCallSignalAddressToMakeCall) && (call->preGrantedArqUse==cmPreGrantedArqDirect))
{
/*direct call without ARQ is allowed*/
if (cmCallGetParam((HCALL)call,cmParamDestCallSignalAddress,0,0,(char*)&ta)>=0)
{
cmCallSetParam((HCALL)call,cmParamDestinationIpAddress,0,0,(char*)&ta);
}
else
{
/*if not exist address do call via GK.*/
if (app->rasGrantedProtocol==1)
{
cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransUseAnnexE,NULL);
cmCallSetParam((HCALL)call,cmParamDestinationAnnexEAddress,0,0,(char*)&app->annexEAddress);
}
else
{
cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransNoAnnexE,NULL);
cmGetGKCallSignalAddress((HAPP)app,&ta);
cmCallSetParam((HCALL)call,cmParamDestinationIpAddress,0,0,(char*)&ta);
}
}
}
else
{
/*routed call without ARQ */
if (app->rasGrantedProtocol==1)
{
cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransUseAnnexE,NULL);
cmCallSetParam((HCALL)call,cmParamDestinationAnnexEAddress,0,0,(char*)&app->annexEAddress);
}
else
{
cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransNoAnnexE,NULL);
cmGetGKCallSignalAddress((HAPP)app,&ta);
cmCallSetParam((HCALL)call,cmParamDestinationIpAddress,0,0,(char*)&ta);
}
}
m_callset(call,dummyRAS,RV_TRUE);
}
}
else if ((app->rasGranted&answerCall) && !(app->rasGranted&useGKCallSignalAddressToAnswer))
{
/* It's an incoming call and we can answer the Setup without an ARQ to the GK */
m_callset(call,dummyRAS,RV_TRUE);
}
}
}
call->rate=call->newRate;
if (!m_callget(call,dummyRAS))
{
/*Automatic RAS*/
cmiAutoRASCallCreate((HCALL)call);
return cmiAutoRASCallDial((HCALL)call);
}
else
{
/* 2004.12.24. fujiangdong. */
HCALL hsCall = (HCALL)call;
autorasEndpoint* autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
autorasCall* autorascall = (autorasCall *)cmiGetAutoRas(hsCall);
/* set the source addresses from the configuration. in automatic RAS, the ARQ will be set */
if (cmCallGetParam(hsCall,cmParamFullSourceAddress,0,NULL,NULL)<0)
cmCallSetParam(hsCall,cmParamFullSourceAddress,0,
pvtGetChild2(app->hVal,app->rasConf,__q931(registrationInfo),__q931(terminalAlias)),NULL);
autorascall->irrTimer = RvH323TimerStartPeriodic(autoras->hTimers, autoRasIrrTimeout, (void*)hsCall, 1000 * app->irrFrequencyInCall);
/*cmiAutoRASCallSetUnsolicitedIRR((HCALL)call, app->irrFrequencyInCall);*/
/* No need to deal with any RAS messages here - continue with the call */
return callStartOK(call);
}
}
/**********************************************************************
* cmSetupEnd
* This function is responsible for the end of the scenatio of receiving
* a setup message. It was taken out of the cmSetup in order to give the
* endpoint time to receive ACF before sending AutoConnect (when autoRas
* and autoConnect are on).
************************************************************************/
int cmSetupEnd(IN callElem* call)
{
cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
HPVT hVal=app->hVal;
int autoAnswer, ret = 0;
if (pvtGetChild(hVal,app->q931Conf,__q931(autoAnswer),NULL)>=0)
{
/* Configuration set to automatically answer any incoming call */
autoAnswer = 1;
}
else
{
autoAnswer = 0;
/* Check if we automatically send Alerting for incoming calls */
if (m_callget(call,sendAlerting))
q931CallAccept(cmiGetQ931((HCALL)call),-1);
}
/*If we are configured to answer the call automatically then do it*/
if (autoAnswer && call->state!=cmCallStateConnected)
ret = callAnswer(call);
return ret;
}
int cmSetup(callElem*call, int message)
{
int ret;
/* Check if we automatically send Call-Proceeding for incoming calls */
if(m_callget(call,sendCallProceeding))
{
q931CallCallProceeding(cmiGetQ931((HCALL)call),-1);
m_callset(call, enableOverlapSending, RV_FALSE);
}
/* We need to analize the fast start before sending the automatic CONNECT message back */
if ((message >=0) && !emaWasDeleted((EMAElement)call))
{
RvInt32 establish=1;
cmCallGetParam((HCALL)call,cmParamEstablishH245,0,&establish,NULL);
if (establish)
analyzeFastStartMsg(call, message);
}
ret = callDial(call);
if ((ret >= 0) && (m_callget(call,dummyRAS)) && (call->state != cmCallStateWaitAddressAck))
ret = cmSetupEnd(call);
return ret;
}
int cmCallProceeding(callElem*call, int message)
{
cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
HPVT hVal=app->hVal;
int tmpNodeId,tmpNodeId1;
__pvtGetNodeIdByFieldIds(tmpNodeId,hVal,message,
{_q931(message) _anyField _q931(userUser) _q931(h323_UserInformation)
_q931(h323_uu_pdu) _q931(h323_message_body) _anyField LAST_TOKEN});
tmpNodeId1=pvtGetChild(hVal,tmpNodeId,__q931(destinationInfo),NULL);
cmCallSetParam((HCALL)call,cmParamFullDestinationInfo,0,tmpNodeId1,NULL);
notifyState((HCALL)call,cmCallStateProceeding,(cmCallStateMode_e)0);
{
int establish=1;
cmCallGetParam((HCALL)call,cmParamEstablishH245,0,&establish,NULL);
if (establish)
if (cmFastStartReply(call,tmpNodeId) >= 0)
deleteFastStart(call);
}
return 0;
}
int cmAlerting(callElem*call, int message)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -