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

📄 cmctrlmsd.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
            res = processMSD(ctrl);
    }
    /* We have already initiated an MSD procedure from our side */
    else if (msd->state==MsdStateOutgoingAwaitingResponse)
    {
        /* close the timer, this message is as good as an ack */
        RvH323TimerCancel(cmGetTimersHandle(hApp),&msd->timer);

        /* activate THE algorithm to determine the master/slave */
        determineStatus(ctrl);

        /* According to the result respond to the remote request */
        if (msd->status==MsdStatusIndeterminate)
        { /* indeterminate: retry sending the request with a new detrmination number */
            countCheckAndSend(ctrl);
        }
        else
        { /* master or slave */

            /* set the result into the control DB, send ack to the remote with the result
               and report the result to the user */
            setAndSendMasterSlave(ctrl,msd->status==MsdStatusMaster, RV_FALSE);
            {
                /* we need an ack on the ack so set a response timer */
                int timeout=9;
                pvtGetChildValue2(hVal,((cmElem*)hApp)->h245Conf,__h245(masterSlave),__h245(timeout),&(timeout),NULL);
                msd->timer=RvH323TimerStart(cmGetTimersHandle(hApp),msdTimeoutEventsHandler,(void*)ctrl,timeout*1000);
            }
            /* we are waiting for ack on the ack */
            msd->state=MsdStateIncomingAwaitingResponse;
        }
    }
    /* the remote has already initiated an MSD procedure with us, this is a mistake */
    else if (msd->state==MsdStateIncomingAwaitingResponse)
          sendErrorResponse(ctrl); /* Error C */
    else if (msd->state==MsdStateIncomingAwaitingManualAcknoledge)
          reportError(ctrl);  /* Error C */

    return res;
}


/************************************************************************
 * masterSlaveDeterminationAck
 * purpose: Handle an incoming MasterSlaveDeterminationAck message
 * input  : ctrl    - Control object
 *          message - MSD.Ack message node
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int masterSlaveDeterminationAck(IN H245Control* ctrl, IN int message)
{
    HAPP             hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
    HPVT             hVal;
    MasterSlaveInfo* msd=&ctrl->msd;
    RvBool           isMaster;

    hVal = ((cmElem *)hApp)->hVal;

    /* Get the remote decision */
    isMaster = (pvtGetChild2(hVal,message,__h245(decision),__h245(master))>=0);

    /* reset the timer, we got response */
    RvH323TimerCancel(cmGetTimersHandle(hApp),&msd->timer);

    /* we are witing for first ACK of our request */
    if (msd->state==MsdStateOutgoingAwaitingResponse)
    {
        /* mark that we have finished at least one MSD procedure, so H.245 may start operate */
        ctrl->bIsMasterSlave=1;

        /* Set the result given by the remote to our control DB, send an ack on this ack
           and report the result to the user */
        setAndSendMasterSlave(ctrl, (int)isMaster, RV_TRUE);
    }
    /* This is actually the ack on the ack we sent */
    else if (msd->state==MsdStateIncomingAwaitingResponse)
    {
        RvBool localIsMaster = (msd->status==MsdStatusMaster);

        /* check if the remote agrees with the result we sent it */
        if (isMaster == localIsMaster)
        {   /* There is an agreement, so the procedure is finished */
            int nesting;
            cmElem *app = (cmElem*)hApp;

            /* mark that we have finished at least one MSD procedure, so H.245 may start operate */
            ctrl->bIsMasterSlave=1;

            /* The procedure is finished - change the state and notify the application */
            msd->state=MsdStateIdle;

            /* Report the result to the user */
            if(app->cmMySessionEvent.cmEvCallMasterSlaveStatus)
            {
                cmiCBEnter(hApp, "cmEvCallMasterSlaveStatus: haCall=0x%p, hsCall=0x%p, status=%s.",(HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),cmiGetByControl((HCONTROL)ctrl), (isMaster)?"master":"slave");
                nesting=emaPrepareForCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl));
                (app->cmMySessionEvent.cmEvCallMasterSlaveStatus)((HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),
                                                                  (HCALL)cmiGetByControl((HCONTROL)ctrl),
                                                                  (RvBool)((isMaster)?cmMSMaster:cmMSSlave));
                emaReturnFromCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl),nesting);
                cmiCBExit(hApp, "cmEvCallMasterSlaveStatus.");
            }
        }
        else
          /* oops! We disagree with the remote, i.e. error state */
          sendErrorResponse(ctrl); /* Error E */
    }

    /* check if the H.245 openning formalities (i.e. TCS & MSD procedures) have ended,
       if so, report to the user that the H.245 is ready for operation */
    cmcReadyEvent(ctrl);
    return RV_TRUE;
}


/************************************************************************
 * masterSlaveDeterminationReject
 * purpose: Handle an incoming MasterSlaveDeterminationReject message
 * input  : ctrl    - Control object
 *          message - MSD.Reject message node
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int masterSlaveDeterminationReject(IN H245Control* ctrl, IN int message)
{
    HAPP             hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
    MasterSlaveInfo* msd=&ctrl->msd;
    if (message);

    /* in case it's a reject on our request */
    if (msd->state==MsdStateOutgoingAwaitingResponse)
    {
        /* reset the timer, we got response */
        RvH323TimerCancel(cmGetTimersHandle(hApp),&msd->timer);
        /* retry sending the request with a new detrmination number */
        countCheckAndSend(ctrl);
    }
    /* if its a reject on the ack that we've sent, it's an error */
    else if (msd->state==MsdStateIncomingAwaitingResponse)
          sendErrorResponse(ctrl); /* Error D */
    else if (msd->state==MsdStateIncomingAwaitingManualAcknoledge)
          reportError(ctrl);  /* Error D */
    return RV_TRUE;
}


/************************************************************************
 * masterSlaveDeterminationRelease
 * purpose: Handle an incoming MasterSlaveDeterminationRelease message
 * input  : ctrl    - Control object
 *          message - MSD.Release message node
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int masterSlaveDeterminationRelease(IN H245Control* ctrl, IN int message)
{
    MasterSlaveInfo* msd=&ctrl->msd;

    if (message);

    /* this isi always an error state if a release was received during the procedure */
    switch(msd->state)
    {
        case MsdStateOutgoingAwaitingResponse:
        case MsdStateIncomingAwaitingResponse:
          sendErrorResponse(ctrl); /* Error B */
        break;
        case MsdStateIncomingAwaitingManualAcknoledge:
          reportError(ctrl);  /* Error B */
        break;
        default:
            break;
    }
    return RV_TRUE;
}


/************************************************************************/
/*                             API                                      */
/************************************************************************/

/************************************************************************
 * cmCallMasterSlaveDetermine
 * purpose: Start master slave determination request
 * input  : hsCall          - The call handle
 *          terminalType    - Our terminal type
 * output : None
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
RVAPI int RVCALLCONV
cmCallMasterSlaveDetermine(
               IN   HCALL       hsCall,
               IN   int         terminalType)
{
    HAPP         hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
    H245Control* ctrl=(H245Control*)cmiGetControl(hsCall);
    int res = RV_ERROR_UNKNOWN;

    if (!hsCall ||  !hApp) return RV_ERROR_UNKNOWN;

    cmiAPIEnter(hApp, "cmMasterSlaveDetermine: hsCall=0x%p, terminalType=%d.", hsCall, terminalType);
    if (emaLock((EMAElement)hsCall))
    {
        res = msdDetermineRequest(ctrl, terminalType, -1);
        emaUnlock((EMAElement)hsCall);
    }

    cmiAPIExit(hApp, "cmMasterSlaveDetermine=%d", res);
    return res;
}

/************************************************************************
 * cmCallMasterSlaveDetermineExt
 * purpose: Start master slave determination request,
 *          or Acknowledge to master slave determination request
 *          and set terminalType and determinationNumber
 * input  : hsCall              - The call handle
 *          terminalType        - A given terminal type
 *          determinationNumber - A given determination number
 * output : None
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
RVAPI int RVCALLCONV
cmCallMasterSlaveDetermineExt(
               IN   HCALL   hsCall,
               IN   int     terminalType,
               IN   int     determinationNumber)
{
    HAPP         hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
    H245Control* ctrl=(H245Control*)cmiGetControl(hsCall);
    int          res = RV_ERROR_UNKNOWN;

    if (!hsCall || !hApp) return RV_ERROR_UNKNOWN;

    cmiAPIEnter(hApp, "cmMasterSlaveDetermineExt: hsCall=0x%p, terminalType=%d determinationNumber = %d. ", hsCall, terminalType,determinationNumber);
    if (emaLock((EMAElement)hsCall))
    {
        res = msdDetermineRequest(ctrl, terminalType, determinationNumber);
        emaUnlock((EMAElement)hsCall);
    }

    cmiAPIExit(hApp, "cmMasterSlaveDetermineExt=%d", res);
    return res;
}


/************************************************************************
 * cmCallMasterSlaveStatus
 * purpose: Returns the master/slave status of this call
 * input  : hsCall              - The call handle
 * output : None
 * return : 1 - slave, 2 - master
 *          Negative value on failure
 ************************************************************************/
RVAPI int RVCALLCONV
cmCallMasterSlaveStatus(
            IN  HCALL       hsCall
            )
{
    HAPP         hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
    int          ret=0;
    H245Control* ctrl=(H245Control*)cmiGetControl(hsCall);
    if (!hsCall || !hApp) return RV_ERROR_UNKNOWN;

    cmiAPIEnter(hApp, "cmCallMasterSlaveStatus: hsCall=0x%p.", hsCall);
    if (emaLock((EMAElement)hsCall))
    {
        if ((ctrl->bIsMasterSlave == 0) || (ctrl->eState == ctrlNotInitialized))
            ret = 0;
        else if (ctrl->bIsMaster)
            ret = 2;
        else
            ret = 1;
        emaUnlock((EMAElement)hsCall);
    }

    {
        char *msStatusA[] = {(char*)"error", (char*)"slave", (char*)"master"};
        cmiAPIExit(hApp, "cmCallMasterSlaveStatus: [%s].", nprn(msStatusA[ret]));
    }
    if (ret==0)
        return RV_ERROR_UNKNOWN;
    else
        return ret;
}


#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -