📄 cmctrlmsd.c
字号:
* Return: Non-negative value on success, other on failure
******************************************************************************/
static int processMSD(H245Control* ctrl)
{
HAPP hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
HPVT hVal;
MasterSlaveInfo* msd=&ctrl->msd;
int nodeId, message, res = RV_ERROR_UNKNOWN;
hVal = ((cmElem *)hApp)->hVal;
/* Initiate THE algorithm to determine master/slave */
determineStatus(ctrl);
if (msd->status==MsdStatusIndeterminate)
{ /* indeterminate */
message=pvtAddRoot(hVal,((cmElem*)hApp)->synProtH245,0,NULL);
__pvtBuildByFieldIds(nodeId,hVal,message, {_h245(response) _h245(masterSlaveDeterminationReject)
_h245(cause) _h245(identicalNumbers) LAST_TOKEN}, 0, NULL);
res = sendMessageH245((HCONTROL)ctrl, message);
pvtDelete(hVal,message);
/* all is over */
msd->state=MsdStateIdle;
}
else
{ /* master or slave */
message=pvtAddRoot(hVal,((cmElem*)hApp)->synProtH245,0,NULL);
__pvtBuildByFieldIds(nodeId,hVal,message, {_h245(response) _h245(masterSlaveDeterminationAck)
_h245(decision) LAST_TOKEN}, 0, NULL);
pvtAddBranch(hVal,nodeId,(msd->status==MsdStatusMaster) ? __h245(slave) : __h245(master));
/* Update the control element as well */
ctrl->bIsMaster = (msd->status==MsdStatusMaster);
ctrl->bIsMasterSlave = 1;
res = sendMessageH245((HCONTROL)ctrl, message);
pvtDelete(hVal,message);
if (res >= 0)
{
/* set a response timer since we need an ack back on our decision */
int timeout=9;
pvtGetChildValue2(hVal,((cmElem*)hApp)->h245Conf,__h245(masterSlave),__h245(timeout),&(timeout),NULL);
RvH323TimerCancel(cmGetTimersHandle(hApp),&msd->timer);
msd->timer=RvH323TimerStart(cmGetTimersHandle(hApp),msdTimeoutEventsHandler,(void*)ctrl,timeout*1000);
/* waiting for the ack on the ack */
msd->state=MsdStateIncomingAwaitingResponse;
}
}
return res;
}
/**************************************************************************************/
/* Internal routines used outside this file */
/**************************************************************************************/
/************************************************************************
* msdInit
* purpose: Initialize the master slave determination process on a control channel
* input : ctrl - Control object
* output : none
* return : none
************************************************************************/
void msdInit(H245Control* ctrl)
{
cmElem* app = (cmElem *)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
HPVT hVal = app->hVal;
MasterSlaveInfo* msd=&ctrl->msd;
msd->status=MsdStatusIndeterminate;
msd->state=MsdStateIdle;
msd->timer=NULL;
msd->myTerminalType=50;
pvtGetChildValue2(hVal,app->h245Conf, __h245(masterSlave), __h245(terminalType),
(RvInt32 *)&(msd->myTerminalType), NULL);
{
RvRandom randomValue;
cmLock((HAPP)app);
RvRandomGeneratorGetValue(&app->randomGenerator, &randomValue);
cmUnlock((HAPP)app);
msd->myStatusDeterminationNumber =
(int)((randomValue * (RvUint32)Rv64Modulu(RvTimestampGet(), 0xffff)) % 0xffffff);
}
msd->manualResponse=(pvtGetChild2(hVal,app->h245Conf,__h245(masterSlave),__h245(manualResponse))>=0);
RvLogInfo(&app->log,
(&app->log, "MSD manual response on %p = %d",ctrl,msd->manualResponse));
}
/************************************************************************
* msdEnd
* purpose: Stop the master slave determination process on a control channel
* input : ctrl - Control object
* output : none
* return : none
************************************************************************/
void msdEnd(IN H245Control* ctrl)
{
MasterSlaveInfo* msd=&ctrl->msd;
HAPP hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
/* Get rid of the timer if one exists */
RvH323TimerCancel(cmGetTimersHandle(hApp),&msd->timer);
}
/*************************************************************************************
* msdDetermineRequest
*
* Purpose: Main routine to initiate or respond to a MSD request.
*
* Input: ctrl - The ctrl element of the call
* terminalType - The given terminal type of the call, may be -1.
* statusDeterminationNumber - The determination numer, may be -1 and then needs to be
* generated.
* Output: None.
*
* return : Non-negative value on success
* Negative value on failure
******************************************************************************************/
int msdDetermineRequest(H245Control* ctrl, int terminalType, int statusDeterminationNumber)
{
HAPP hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
cmElem* app = (cmElem *)hApp;
HPVT hVal;
MasterSlaveInfo* msd=&ctrl->msd;
int nodeId, message, res = RV_ERROR_UNKNOWN;
/** 2004.10.07. modified. When h245tunneling is on, the msd->state is 2, so
* we delete this code.
*/
#if 0
if((msd->state!=MsdStateIdle) && (msd->state!=MsdStateIncomingAwaitingManualAcknoledge))
return RV_ERROR_UNKNOWN;
#endif
hVal = app->hVal;
/* if this is a new MSD process, re-generate the random determenition number */
/** 2004.10.07. modified. When h245tunneling is on, the msd->state is 2, so
* we delete this code.
*/
#if 0
if (msd->state == MsdStateIdle)
#endif
{
/* if the determination number is -1, generate a new random 24 bit determination number */
if (statusDeterminationNumber < 0)
{
RvRandom randomValue;
cmLock(hApp);
RvRandomGeneratorGetValue(&app->randomGenerator, &randomValue);
cmUnlock(hApp);
statusDeterminationNumber =
(int)((randomValue * (RvUint32)Rv64Modulu(RvTimestampGet(), 0xffff)) % 0xffffff);
}
msd->myStatusDeterminationNumber=statusDeterminationNumber;
}
/* if terminal type is not given, i.e. -1, we just use the one from msdInit */
if (terminalType >= 0)
msd->myTerminalType=terminalType;
/* if the procedure hasn't started yet initiate it */
/** 2004.10.07. modified. When h245tunneling is on, the msd->state is 2, so
* we modified this code.
*/
#if 0
if (msd->state==MsdStateIdle)
#endif
if (msd->state!=MsdStateIncomingAwaitingManualAcknoledge)
{
/* build the request message with the terminaType and determinationNumber */
message=pvtAddRoot(hVal,app->synProtH245,0,NULL);
nodeId=pvtAddBranch2(hVal,message,__h245(request), __h245(masterSlaveDetermination));
pvtAdd(hVal,nodeId,__h245(statusDeterminationNumber),msd->myStatusDeterminationNumber, NULL,NULL);
pvtAdd(hVal,nodeId,__h245(terminalType),msd->myTerminalType, NULL,NULL);
/* Initialize the retry mechanism and send the message */
msd->count=1;
res = sendMessageH245((HCONTROL)ctrl, message);
pvtDelete(hVal,message);
if (res >= 0)
{
/* Make sure message was actually sent and we didn't use a "dummy" H245 (as in the GK's MC) */
if (!simulatedMessageH245((HCONTROL)ctrl))
{
/* We're only here if we really sent the message */
/* start a timer to wait for response */
/**
* 2004.09.24. modified by mxd. Not to start the timer.
*/
/*int timeout=9;
pvtGetChildValue2(hVal,app->h245Conf,__h245(masterSlave),__h245(timeout),&(timeout),NULL);
RvH323TimerCancel(cmGetTimersHandle(hApp),&msd->timer);
msd->timer=RvH323TimerStart(cmGetTimersHandle(hApp),msdTimeoutEventsHandler,(void*)ctrl,timeout*1000);
*/
/* change the state of the procedure */
msd->state=MsdStateOutgoingAwaitingResponse;
}
}
}
else if (msd->state==MsdStateIncomingAwaitingManualAcknoledge)
{
/* in case that we are in a state waiting to respond to a request, build the response and send it */
res = processMSD(ctrl);
}
return res;
}
/************************************************************************
* msdGetMibParams
* purpose: Get parameters related to the MIB for an MSD object in the
* control
* input : ctrl - Control object
* output : state - State of MSD
* status - Status of MSD
* retries - Number of MSD retries
* terminalType - Local terminal's type in MSD
* return : Non-negative value on success
* Negative value on failure
* Any of the output parameters can be passed as NULL if not relevant to caller
************************************************************************/
int msdGetMibParams(
IN H245Control* ctrl,
OUT MsdState* state,
OUT MsdStatus* status,
OUT int* retries,
OUT int* terminalType)
{
if (state)
*state = ctrl->msd.state;
if (status)
*status = ctrl->msd.status;
if (retries)
*retries = ctrl->msd.count;
if (terminalType)
*terminalType = ctrl->msd.myTerminalType;
return 0;
}
/**************************************************************************************/
/* Handling incoming MSD messages */
/**************************************************************************************/
/************************************************************************
* masterSlaveDetermination
* purpose: Handle an incoming MasterSlaveDetermination request,
* notifying the application or answering automatically.
* input : ctrl - Control object
* message - MSD request message node
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int masterSlaveDetermination(IN H245Control* ctrl, IN int message)
{
HAPP hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
HPVT hVal;
MasterSlaveInfo* msd=&ctrl->msd;
int res = 0;
hVal = ((cmElem *)hApp)->hVal;
/* get the remote numbers from the message */
pvtGetChildValue(hVal,message,__h245(terminalType),&(msd->terminalType),NULL);
pvtGetChildValue(hVal,message,__h245(statusDeterminationNumber),&(msd->statusDeterminationNumber),NULL);
/* if we have not initiated yet an MSD procedure */
if (msd->state==MsdStateIdle)
{
cmElem *app = (cmElem*)hApp;
/* in case of manual response, inform the application of the initiation */
if ( (msd->manualResponse) && (app->cmMySessionEvent.cmEvCallMasterSlave) )
{
int nesting;
msd->state=MsdStateIncomingAwaitingManualAcknoledge;
cmiCBEnter(hApp, "cmEvCallMasterSlave: haCall=0x%p, hsCall=0x%p, terminalType =%d, statusDeterminationNumber = %d.",
(HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),cmiGetByControl((HCONTROL)ctrl), ctrl->msd.terminalType,ctrl->msd.statusDeterminationNumber);
nesting=emaPrepareForCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl));
(app->cmMySessionEvent.cmEvCallMasterSlave)((HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),(HCALL)cmiGetByControl((HCONTROL)ctrl), (RvUint32)ctrl->msd.terminalType, (RvUint32)ctrl->msd.statusDeterminationNumber);
emaReturnFromCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl),nesting);
cmiCBExit(hApp, "cmEvCallMasterSlave.");
}
else
/* Automatic response: Determine the ,aster/slave and issue a response */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -