📄 cmautorascall.c
字号:
* trStage - Stage of response
* output : none
* return : non-negative value on success
* negative value on failure
************************************************************************/
int RVCALLCONV autoRasRegAndSendAftDisc
(
IN HAPPRAS haRas,
IN HRAS hsRas,
IN cmRASTrStage trStage
)
{
int ret=RV_ERROR_UNKNOWN, responseId = cmiRASGetResponse(hsRas);
autorasCall* autorasC = (autorasCall *)haRas;
HCALL hsCall = cmiGetByAutoRas((HAUTORASCALL)autorasC);
autorasEndpoint* autorasE = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
switch(trStage)
{
case cmRASTrStageConfirm:
{
/* cool, now let's send the RRQ. first we have to get the address */
int tmpNodeId;
cmTransportAddress GkAddr;
cmRASAlias * GkIdPtr = NULL;
cmRASAlias GkId;
char IdSrt[128];
GkId.string = IdSrt;
__pvtGetByFieldIds(tmpNodeId, autorasE->hVal, responseId,
{ _q931(gatekeeperConfirm) _q931(rasAddress) LAST_TOKEN }, NULL, NULL, NULL);
cmVtToTA(autorasE->hVal, tmpNodeId, &GkAddr);
__pvtGetByFieldIds(tmpNodeId, autorasE->hVal, responseId,
{ _q931(gatekeeperConfirm) _q931(gatekeeperIdentifier) LAST_TOKEN }, NULL, NULL, NULL);
if(tmpNodeId>=0)
{
GkIdPtr = &GkId;
GkId.length = (unsigned short) pvtGetString(autorasE->hVal, tmpNodeId, 128, IdSrt);
}
cmRASClose(hsRas);
autorasE->registrationTx = NULL;
ret = autoRasRegAndSend(autorasE, autorasC, &GkAddr, GkIdPtr);
return ret;
}
case cmRASTrStageReject:
autorasC->wasRejected = RV_TRUE;
case cmRASTrStageTimeout:
{
/* Let's register to the next GK */
if((ret = autoRasCallSendToNextGK(autorasE, autorasC)) < 0)
{
/* Drek. could not send the ARQ, maybe because there are no more GKs. */
if(autorasC->wasRejected)
{
autorasC->wasRejected = RV_FALSE;
autorasC->isTempRdrn = RV_FALSE;
autorasE->event(hsCall, hsRas, cmiAutoRasEvCallRejected);
break;
}
autorasE->event(hsCall, hsRas, cmiAutoRasEvTimedout);
/* See if we should try to register again */
if(autorasC->isTempRdrn)
{
/* just a temp redirection, forget it */
autorasC->isTempRdrn = RV_FALSE;
break;
}
if (pvtGetChild(autorasE->hVal, autorasE->confNode, __q931(dontRegisterOnTimeout), NULL) < 0)
{
/* We should change the status to not registered */
autorasE->state = cmIdle;
autoRasCallIdleState(autorasE, autorasC);
/* Make sure we're trying to register again */
if ((autorasE->internalState != autorasRegTrying) && (autorasE->internalState != autorasRegFailed))
cmRegister(autorasE->hApp);
}
}
}
default:
/* This shouldn't happen... */
break;
}
if (hsRas == autorasE->registrationTx)
{
cmRASClose(hsRas);
autorasE->registrationTx = NULL;
}
return ret;
}
/************************************************************************
* autoRasDiscRegAndSend
* purpose: Send GRQ for an Alt Gk which answered with discoveryRequired
* input : autorasE - Automatic RAS module for an EP
* autorasC - Automatic RAS module for a call
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int autoRasDiscRegAndSend
(
IN autorasEndpoint* autorasE,
IN autorasCall* autorasC
)
{
int ret, tmpNode;
cmTransportAddress GkAddr;
int GKnode = autoRasGetCurrentAltGkNode(autorasE, autorasC);
if (GKnode<0)
/* SHOULD NOT BE HERE !! */
return RV_ERROR_UNKNOWN;
tmpNode = pvtGetChild(autorasE->hVal, GKnode, __q931(rasAddress), NULL);
if(tmpNode>=0) cmVtToTA(autorasE->hVal, tmpNode, (cmTransportAddress *) &GkAddr);
if (autorasE->registrationTx != NULL)
{
cmRASClose(autorasE->registrationTx);
autorasE->registrationTx = NULL;
}
ret = cmRASStartTransaction(autorasE->hApp, (HAPPRAS)autorasC,
&autorasE->registrationTx, cmRASGatekeeper, &GkAddr, NULL);
if (ret >= 0)
{
cmAlias GKID;
char GKIDstr[128];
int GKIDnode = pvtGetChild(autorasE->hVal, GKnode, __q931(gatekeeperIdentifier), NULL);
GKID.string = GKIDstr;
if((GKIDnode>=0) &&
((GKID.length = (unsigned short) pvtGetString(autorasE->hVal, GKIDnode, 128, GKIDstr))>0))
cmRASSetParam(autorasE->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(GKID), (char *)&GKID);
/* Set the parameters of the message */
cmRASSetParam(autorasE->registrationTx, cmRASTrStageRequest, cmRASParamDiscoveryComplete, 0, (RvInt32)autorasE->discoveryComplete, NULL);
cmRASSetParam(autorasE->registrationTx, cmRASTrStageRequest, cmRASParamKeepAlive, 0, 0, NULL);
/* Make sure next time we know nothing about a GCF */
autorasE->discoveryComplete = RV_FALSE;
/* Set the response handler for this message */
cmiRASSetTrEventHandler(autorasE->registrationTx, autoRasRegAndSendAftDisc);
/* Send the request */
ret = cmRASRequest(autorasE->registrationTx);
}
return ret;
}
/************************************************************************
* autoRasIrrTimeout
* purpose: Callback function which sends an unsolicited IRR on a call
* input : context - autoras call handle
* output : none
* return : none
************************************************************************/
RvBool autoRasIrrTimeout(IN void* context)
{
HCALL hsCall = (HCALL)context;
autorasEndpoint* autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
autorasCall* call = (autorasCall *)cmiGetAutoRas(hsCall);
int res;
/* Create an IRR transaction and fill it in with the call's information
We're leaving this transaction open as we're sending it on each timeout
event for the IRR */
if (call->irrTx != NULL)
cmRASClose(call->irrTx);
res = cmRASStartTransaction(autoras->hApp, (HAPPRAS)call, &call->irrTx,
cmRASUnsolicitedIRR, NULL, hsCall);
if (res >= 0)
{
cmRASRequest(call->irrTx);
}
return RV_TRUE;
}
/************************************************************************
* autoRasCallTransaction
* purpose: Callback function used for automatic RAS for dealing with
* incoming transactions related to specific calls
* input : hApp - Stack instance handle
* hsRas - Stack's handle for the RAS transaction
* hsCall - Stack's call handle
* transaction - The type of transaction that arrived
* srcAddress - Address of the source
* haCall - Application's call handle
* notifyCb - Callback for application about the request
* output : none
* return : RV_TRUE if message was processed by this callback and shouldn't
* be processed by the manual RAS callbacks
* RV_FALSE if message wasn't processed by this callback
************************************************************************/
RvBool RVCALLCONV autoRasCallTransaction(
IN HAPP hApp,
IN HRAS hsRas,
IN HCALL hsCall,
IN cmRASTransaction transaction,
IN cmRASTransport* srcAddress,
IN HAPPCALL haCall,
IN cmEvAutoRASRequestT notifyCb)
{
autorasCall* call = (autorasCall *)cmiGetAutoRas(hsCall);
if (haCall || srcAddress);
/* Notify the application if we have to */
if (notifyCb != NULL)
{
switch (transaction)
{
case cmRASDisengage:
case cmRASBandwidth:
case cmRASInfo:
cmiCBEnter(hApp, "cmEvAutoRASRequest(hsRas=0x%p,hsCall=0x%p,trans=%d)", hsRas, hsCall, transaction);
notifyCb(hsRas, hsCall, transaction, srcAddress, haCall);
cmiCBExit(hApp, "cmEvAutoRASRequest(hsRas=0x%p)", hsRas);
break;
default:
/* Not through automatic RAS... */
break;
}
}
/* See what we've got */
if (emaLock((EMAElement)hsCall))
{
switch (transaction)
{
case cmRASDisengage:
{
/* DRQ - automatically confirm it */
autorasEndpoint* autoras;
autorasCallState state = call->callState;
call->callState = autorasCallDisconnecting;
autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
/* Always send DCF on this one and close the transaction */
cmRASConfirm(hsRas);
cmRASClose(hsRas);
/* We should get back to the idle state of the transaction */
autoRasCallIdleState(autoras, call);
if (state != autorasCallDisconnecting)
{
/* Notify application about this situation */
autoras->event(hsCall, hsRas, cmiAutoRasEvCallDropForced);
}
break;
}
case cmRASBandwidth:
{
/* BRQ - always confirm it */
autorasEndpoint* autoras;
autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
autoras->event(hsCall, hsRas, cmiAutoRasEvRateChanged);
cmRASConfirm(hsRas);
cmRASClose(hsRas);
break;
}
case cmRASInfo:
{
/* IRQ on call - always confirm it */
cmRASConfirm(hsRas);
cmRASClose(hsRas);
break;
}
default:
{
/* Not processed by automatic RAS */
/* 2004.11.03, added. make sure we unlock the mutex */
emaUnlock((EMAElement)hsCall);
return RV_FALSE;
}
}
emaUnlock((EMAElement)hsCall);
}
/* Make sure manual RAS knowns we have processed this mesage */
return RV_TRUE;
}
/************************************************************************
* autoRasBandwidthResponse
* purpose: Callback function invoked when a response for BRQ arrives
* input : haRas - Application's handle (autoras in this context)
* hsRas - RAS Transaction handle
* trStage - Stage of response
* output : none
* return : non-negative value on success
* negative value on failure
************************************************************************/
int RVCALLCONV autoRasBandwidthResponse
(
IN HAPPRAS haRas,
IN HRAS hsRas,
IN cmRASTrStage trStage)
{
autorasEndpoint* autoras;
autorasCall* call = (autorasCall *)haRas;
HCALL hsCall = cmiGetByAutoRas((HAUTORASCALL)call);
int rv = RV_ERROR_UNKNOWN;
int responseId = cmiRASGetResponse(hsRas);
if (emaLock((EMAElement)hsCall))
{
autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
/* See what we've got for the BRQ */
switch(trStage)
{
case cmRASTrStageConfirm:
{
/* this function will set the new GK if needed, and get the new AltGKs list */
setRasAlternateGatekeeper(autoras, call,
pvtGetChild(autoras->hVal, responseId, __q931(alternateGatekeeper), NULL));
break;
}
case cmRASTrStageReject:
{
int chNodeId;
/* See if this is a redirection */
__pvtGetNodeIdByFieldIds(chNodeId, autoras->hVal, responseId, {_anyField _q931(altGKInfo) LAST_TOKEN});
if (chNodeId >= 0)
{
/* Se we are redirected to an AltGK.*/
RvInt32 isPerm;
int newAltGKs;
call->wasRejected = RV_TRUE;
/* maybe we are already working on a redirection */
if(!autoRasIsInSearch(autoras,call))
{
/* We're not working on anything right now - we start redirection */
/* Let's see if permanently of temporeraly */
newAltGKs = pvtGetChild(autoras->hVal, chNodeId, __q931(alternateGatekeeper), NULL);
pvtGetChildByFieldId(autoras->hVal, chNodeId, __q931(altGKisPermanent), &isPerm, NULL);
if(isPerm)
autoRasSetPermList(autoras, newAltGKs);
else
{
call->isTempRdrn = RV_TRUE;
autoRasSetTempList(autoras, newAltGKs);
}
}
/* ok, let's send the old messsage to a new GK */
if(autoRasCallSendToNextGK(autoras, call) >= 0)
{
/* Sent ok */
/* Make sure we close this transaction if it wasn't already closed */
emaUnlock((EMAElement)hsCall);
return 0;
}
else
{ /* Otherwise we are rejected for good */
call->isTempRdrn = RV_FALSE;
call->wasRejected = RV_FALSE;
autoRasResetSearch(autoras,NULL);
}
}
else
setRasAlternateGatekeeper(autoras, call, -1);
break;
}
case cmRASTrStageTimeout:
{
/* timedout... */
cmElem* app = (cmElem *)emaGetInstance((EMAElement)hsCall);
/* maybe we are already working on a redirection, or
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -