⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmctrlmsd.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
 * 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 + -