📄 cmautorasep.c
字号:
/************************************************************************
* autoRasPrepareGRQ
* purpose: Send a GRQ message to a gatekeeper trying to register it
* input : autoras - Automatic RAS instance to register
* output : none
* return : non-negative value on success
* negative value on failure
************************************************************************/
static int autoRasPrepareGRQ(IN autorasEndpoint* autoras)
{
int ret;
int GKnode = RV_ERROR_UNKNOWN;
cmRASTransport GKAddr;
cmRASTransport * GKAddrPtr = NULL;
/* Make sure we have no pending transactions */
if (autoras->registrationTx != NULL)
{
cmRASClose(autoras->registrationTx);
autoras->registrationTx = NULL;
}
if(autoRasGotPermList(autoras))
{
GKnode = autoRasGetCurrentAltGkNode(autoras,NULL);
if(GKnode < 0)
{ /* no more GKs in AltGKs list - get rid of it */
autoRasRemovePermList(autoras);
autoRasResetSearch(autoras,NULL);
}
else
{ /* Got a GK from the list - Get it's address */
int GKAddrNode = pvtGetChild(autoras->hVal, GKnode, __q931(rasAddress), NULL);
if((GKAddrNode>=0) && (cmVtToTA(autoras->hVal, GKAddrNode, (cmTransportAddress *) &GKAddr)>=0))
GKAddrPtr = &GKAddr;
}
}
/* Create the transaction - default destination (=gk) or the one we found */
ret = cmRASStartTransaction(autoras->hApp, (HAPPRAS)autoras, &autoras->registrationTx, cmRASGatekeeper, GKAddrPtr, NULL);
if (ret >= 0)
{
if(GKnode < 0)
{ /* not using AltGK. send a multicast request */
/* Set the multicast parameter to indicate this as a multicast message */
cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamMulticastTransaction, 0, RV_TRUE, NULL);
}
else
{ /* using an AltGK */
/* Set the Gatkeeper ID to the indicated one (if indicated) */
cmAlias GKID;
char GKIDstr[128];
int GKIDnode = pvtGetChild(autoras->hVal, GKnode, __q931(gatekeeperIdentifier), NULL);
GKID.string = GKIDstr;
if((GKIDnode>=0) &&
((GKID.length = (unsigned short) pvtGetString(autoras->hVal, GKIDnode, 128, GKIDstr))>0))
cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(GKID), (char *) &GKID);
}
/* Set the response handler for this message */
cmiRASSetTrEventHandler(autoras->registrationTx, autoRasGatekeeperResponse);
/* Send the request */
ret = cmRASRequest(autoras->registrationTx);
if (ret < 0)
{
/* We're not going to get any events on this transaction. We might as well
just simulate waiting for a result and timing-out on that one to continue
on trying */
rasModule * rasMdl = (rasModule *)cmiGetRasHandle(autoras->hApp);
int timeout;
timeout = rasCfgGetTimeout(rasMdl) * rasCfgGetRetries(rasMdl);
RvH323TimerCancel(autoras->hTimers, &autoras->regTimer);
autoras->regTimer = RvH323TimerStart(autoras->hTimers, autorasTryToRegisterOnError, autoras, timeout);
}
}
return ret;
}
/************************************************************************
* autoRasPrepareRRQ
* purpose: Send an RRQ message to a gatekeeper trying to register it
* input : autoras - Automatic RAS instance to register
* GkNodeId - Node Id of Alt GK to try, RV_ERROR_UNKNOWN if none.
* output : none
* return : non-negative value on success
* negative value on failure
************************************************************************/
static int autoRasPrepareRRQ(IN autorasEndpoint* autoras, IN int GkNodeId)
{
int ret;
cmRASTransport GKAddr;
cmTransportAddress * addrPtr = NULL;
/* Make sure we have no pending transactions */
if (autoras->registrationTx != NULL)
{
cmRASClose(autoras->registrationTx);
autoras->registrationTx = NULL;
}
/* Check to see if this is a redirection */
if(GkNodeId >=0 )
{
/* Got a GK - Get it's address */
int GKAddrNode = pvtGetChild(autoras->hVal, GkNodeId, __q931(rasAddress), NULL);
if((GKAddrNode>=0) && (cmVtToTA(autoras->hVal, GKAddrNode, (cmTransportAddress *) &GKAddr)>=0))
addrPtr = &GKAddr;
}
/* Maybe we already found an Alt GK */
else
if(autoras->setGK.port)
addrPtr = &autoras->setGK;
/* Create the transaction - default destination (=gk) or the AltGK we found */
ret = cmRASStartTransaction(autoras->hApp, (HAPPRAS)autoras, &autoras->registrationTx, cmRASRegistration, addrPtr, NULL);
if (ret >= 0)
{
cmAlias GKID;
char GKIDstr[128];
GKID.string = GKIDstr;
/* Set the parameters of the message */
cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamDiscoveryComplete, 0, (RvInt32)autoras->discoveryComplete, NULL);
cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamKeepAlive, 0, 0, NULL);
/* Check to see if this is a redirection */
if(GkNodeId >=0)
{
/* Set the Gatkeeper ID to the indicated one (if indicated) */
int GKIDnode = pvtGetChild(autoras->hVal, GkNodeId, __q931(gatekeeperIdentifier), NULL);
if((GKIDnode>=0) &&
((GKID.length = (unsigned short) pvtGetString(autoras->hVal, GKIDnode, 128, GKIDstr))>0))
cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(GKID), (char *) &GKID);
}
/* Maybe we already found an Alt GK */
else if(autoras->GKID.length)
cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(autoras->GKID), (char *) &autoras->GKID);
/* Make sure next time we know nothing about a GCF */
autoras->discoveryComplete = RV_FALSE;
/* Set the response handler for this message */
cmiRASSetTrEventHandler(autoras->registrationTx, autoRasRegistrationResponse);
/* Send the request */
ret = cmRASRequest(autoras->registrationTx);
if (ret < 0)
{
/* We're not going to get any events on this transaction. We might as well
just simulate waiting for a result and timing-out on that one to continue
on trying */
rasModule * rasMdl = (rasModule *)cmiGetRasHandle(autoras->hApp);
int timeout;
timeout = rasCfgGetTimeout(rasMdl) * rasCfgGetRetries(rasMdl) * 1000;
RvH323TimerCancel(autoras->hTimers, &autoras->regTimer);
autoras->regTimer = RvH323TimerStart(autoras->hTimers, autorasTryToRegisterOnError, autoras, timeout);
}
}
return ret;
}
/************************************************************************
* autoRasTryToRegister
* purpose: Start registration process of the endpoint
* input : autoras - Automatic RAS instance to register
* output : none
* return : non-negative value on success
* negative value on failure
************************************************************************/
static int autoRasTryToRegister(IN autorasEndpoint* autoras)
{
RvInt32 maxFail;
int status;
if (autoras->internalState != autorasRegFailed)
autoras->internalState = autorasRegTrying;
autoras->regTries++; /* another try... */
/* Make sure we reset the timer if we have any */
RvH323TimerCancel(autoras->hTimers, &autoras->regTimer);
/* Make sure we have no pending transactions */
if (autoras->registrationTx != NULL)
{
cmRASClose(autoras->registrationTx);
autoras->registrationTx = NULL;
}
/* See if we're done trying */
/* ToDo: compensate for AltGKs */
if ((pvtGet(autoras->hVal, pvtGetChild(autoras->hVal, autoras->confNode, __q931(maxFail), NULL), NULL, NULL, &maxFail, NULL) < 0) || (maxFail == 0))
maxFail = 1;
if ((autoras->regTries > maxFail) && (autoras->internalState != autorasRegFailed))
{
autoras->internalState = autorasRegFailed;
/* We continue on trying to register although we failed - here, we just allow calls
to be created */
/* Notify the application that we're not registered although the user wanted to */
status = autoRasChangeState(autoras, cmRegistrationConfirm, RV_PVT_INVALID_NODEID);
/* In case someone called cmUnregister or cmRegister in the callback, do not send another RRQ */
if ( (autoras->internalState == autorasRegNotTried) || (autoras->internalState == autorasRegTrying) )
return 0;
}
/* See if we're in GRQ or RRQ */
__pvtGetByFieldIds(status, autoras->hVal, autoras->confNode, {_q931(manualDiscovery) _q931(defaultGatekeeper) LAST_TOKEN}, NULL, NULL, NULL)
if ((status >= 0) && (!autoras->discoveryRequired))
{
/* We've got a GK address that didn't reject us yet - start from RRQ */
return autoRasPrepareRRQ(autoras, RV_ERROR_UNKNOWN);
}
else
{
/* We don't have any GK address, or were rejected by GK - start from GRQ */
if(autoRasGotPermList(autoras))
{
/* We are using Alt GKs - be sure to try the next one */
autoRasGetNextAltGkNode(autoras,NULL);
}
return autoRasPrepareGRQ(autoras);
}
}
/************************************************************************
* autorasTryToRegisterOnError
* purpose: Timeout function after simulating a timeout on a transaction
* that we couldn't get started properly.
* input : context - Automatic RAS handle
* output : none
* return : none
************************************************************************/
static RvBool autorasTryToRegisterOnError(IN void* context)
{
autorasEndpoint *autoras = (autorasEndpoint *)context;
/* Reset the timer if we have any */
RvH323TimerClear(autoras->hTimers, &autoras->regTimer);
/* Try to register all over again */
autoRasTryToRegister(autoras);
return RV_FALSE;
}
/************************************************************************
* autoRasIdleAndRegister
* purpose: Change the state of the Automatic RAS endpoint handling to
* idle and retry registration
* input : autoras - Automatic RAS handle
* output : none
* return : non-negative value on success
* negative value on failure
************************************************************************/
static void autoRasIdleAndRegister(IN autorasEndpoint* autoras)
{
/* Change the state back to Idle if we have to */
if (autoras->state != cmIdle)
{
autoras->state = cmIdle;
autoras->internalState = autorasRegTrying;
autoRasChangeState(autoras, (cmRegEvent)-1, RV_PVT_INVALID_NODEID);
if(autoras->internalState == autorasRegNotTried)
/* someone decided to unregister in the above event */
return;
}
/* Try to register again */
autoRasTryToRegister(autoras);
}
/************************************************************************
* autoRasEPTransaction
* purpose: Callback function that handles incoming endpoint-related
* transactions
* input : hApp - Stack instance handle
* hsRas - RAS transaction handle
* transaction - Transaction type of incoming message
* srcAddress - Address of the message's origin
* 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
************************************************************************/
static RvBool RVCALLCONV autoRasEPTransaction(
IN HAPP hApp,
IN HRAS hsRas,
IN cmRASTransaction transaction,
IN cmRASTransport* srcAddress,
IN cmEvAutoRASRequestT notifyCb)
{
if (srcAddress); /* Remove warning from compilation */
/* Tell the application about this request... */
if (notifyCb != NULL)
{
switch (transaction)
{
case cmRASUnregistration:
case cmRASNonStandard:
case cmRASInfo:
cmiCBEnter(hApp, "cmEvAutoRASRequest(hsRas=0x%p,hsCall=0x0,trans=%d)", hsRas, transaction);
notifyCb(hsRas, NULL, transaction, srcAddress, NULL);
cmiCBExit(hApp, "cmEvAutoRASRequest(hsRas=0x%p)", hsRas);
break;
default:
/* Not handled by Automatic RAS... */
break;
}
}
/* Check the type of transaction we're dealing with */
switch (transaction)
{
case cmRASUnregistration:
{
/* URQ message - always send back a UCF */
autorasEndpoint* autoras = (autorasEndpoint *)cmiGetAutoRasHandle(cmiRASGetHAPP(hsRas));
int requestId = cmiRASGetRequest(hsRas);
int nodeId;
int newAltGKs = RV_ERROR_UNKNOWN;
/* First - let's move to idle */
autoras->state = cmIdle;
autoRasChangeState(autoras, cmUnregistrationRequest, requestId);
/* now, let's confirm it */
cmRASConfirm(hsRas);
/* Now see if we were redirected */
__pvtGetNodeIdByFieldIds(newAltGKs, autoras->hVal, requestId, {_anyField _q931(alternateGatekeeper) LAST_TOKEN});
if (newAltGKs >= 0)
{
/* Se we are redirected to an AltGK.*/
/* maybe we are already working on a redirection */
if(autoRasIsInSearch(autoras,NULL))
{
/* We're working on a redirection, but we'd like to reset it */
autoRasSetPermList(autoras, newAltGKs);
autoRasResetSearch(autoras, NULL);
autoras->isTempRdrn = RV_FALSE;
autoRasRemoveTempList(autoras);
cmRASClose(hsRas);
if(autoras->registrationTx)
{
cmRASClose(autoras->registrationTx);
autoras->registrationTx = 0;
}
}
else
{
autoRasSetPermList(autoras, newAltGKs);
autoRasRemoveTempList(autoras);
}
/* we're starting redirection: let's get a gatekeeper */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -