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

📄 cmchan.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:



/* H245Channel Operations______________________________________________________________________*/




RVAPI int RVCALLCONV
cmSetChannelEventHandler(
             /* Set user callbacks functions for control channels. */
             IN HAPP        hApp,
             IN     CMCHANEVENT cmChannelEvent,
             IN     int     size)
{
  cmElem *app = (cmElem *)hApp;

  if (!app) return RV_ERROR_UNKNOWN;

  cmiAPIEnter(hApp, "cmSetChannelEventHandler: hApp=0x%p, cmChannelEvent=0x%p, size=%d.", hApp, cmChannelEvent, size);
  memset(&app->cmMyChannelEvent, 0, sizeof(app->cmMyChannelEvent));
  memcpy(&app->cmMyChannelEvent, cmChannelEvent, RvMin((int)sizeof(app->cmMyChannelEvent), (RvSize_t)size));
  cmiAPIExit(hApp, "cmSetChannelEventHandler: [0].");
  return 0;
}

RVAPI
int RVCALLCONV cmGetChannelEventHandler(
        IN      HAPP                hApp,
        OUT      CMCHANEVENT         cmChannelEvent,
        IN      int                 size)
{
  cmElem *app = (cmElem *)hApp;

  if (!app) return RV_ERROR_UNKNOWN;

  cmiAPIEnter(hApp, "cmGetChannelEventHandler: hApp=0x%p, cmChannelEvent=0x%p, size=%d.", hApp, cmChannelEvent, size);
  memset(cmChannelEvent, 0, sizeof(app->cmMyChannelEvent));
  memcpy(cmChannelEvent, &app->cmMyChannelEvent, RvMin((int)sizeof(app->cmMyChannelEvent), (RvSize_t)size));
  cmiAPIExit(hApp, "cmGetChannelEventHandler: [0].");
  return 0;
}

H245Channel* allocateChannel(HCONTROL ctrl)
{
    H245Channel channel,*ch = NULL;
    memset(&channel,0xff,sizeof(H245Channel));
    channel.pChannelParams.data.h225Params.fastStartChannelIndex=-1;
    channel.pChannelParams.data.h225Params.dynamicPayloadNumber=-1;
    channel.pPartner=NULL;
    channel.pBase=NULL;
    channel.pAssociated=NULL;
    channel.pReplacementCh=NULL;
    channel.bIsDuplex=0; /* by default it is simplex (uni-directional) channel. */
    channel.sessionId=0;
    channel.pChannelParams.data.h225Params.bFlowControlToZero =0;
    if (((H245Control*)ctrl)->logicalChannelOut<1)
        ((H245Control*)ctrl)->logicalChannelOut=1;
    channel.myLogicalChannelNum=++((H245Control*)ctrl)->logicalChannelOut;
    channel.reverseLogicalChannelNum=0;
    channel.hCtrl=ctrl;
    channel.bOrigin=RV_TRUE;
    channel.pChannelParams.data.h225Params.recvRtcpAddressID=RV_ERROR_UNKNOWN;
    channel.pChannelParams.data.h225Params.recvRtpAddressID=RV_ERROR_UNKNOWN;
    channel.pChannelParams.data.h225Params.sendRtcpAddressID=RV_ERROR_UNKNOWN;
    channel.pChannelParams.data.h225Params.sendRtpAddressID=RV_ERROR_UNKNOWN;
    channel.pChannelParams.data.h225Params.redEncID=RV_ERROR_UNKNOWN;
    channel.pChannelParams.data.h225Params.transCapID=RV_ERROR_UNKNOWN;
    channel.pChannelParams.data.h225Params.separateStackID=RV_ERROR_UNKNOWN;
    channel.pChannelParams.data.h225Params.t120SetupProcedure=0;
    channel.requestCloseParamID=RV_ERROR_UNKNOWN;
    channel.dataTypeID=RV_ERROR_UNKNOWN;
    channel.eState=ChannelStateIdle;
    channel.pChannelParams.data.h225Params.portNumber=RV_ERROR_UNKNOWN;
    channel.remotePortNumber=RV_ERROR_UNKNOWN;
    channel.pTimer = NULL;
    channel.pRequestCloseTimer = NULL;
    channel.pMediaLoopTimer = NULL;
    channel.pNext = NULL;
    channel.pPrev = NULL;
    ch = (H245Channel *)emaAdd(((cmElem*)(emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl))))->hChannels,NULL);
    if (ch)
    {
        H245Channel * chanList = (H245Channel *) cmiGetChannelListForCtrl(ctrl);

        emaLinkToElement((EMAElement)ch, (EMAElement)cmiGetByControl(ctrl));

        memcpy(ch,&channel,sizeof(H245Channel));
        if (chanList)
        {
            /* add to channel list */
            ch->pNext = chanList;
            chanList->pPrev = ch;
        }
        cmiSetChannelListForCtrl(ctrl, (HCHAN) ch);
    }
    return ch;
}


RVAPI int RVCALLCONV
cmChannelNew (
          IN    HCALL       hsCall,
          IN    HAPPCHAN    haChan,
          OUT   LPHCHAN     lphsChan)
{
    HCONTROL ctrl=cmiGetControl(hsCall);
    H245Channel*channel;
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
    if (!hsCall || !hApp) return RV_ERROR_UNKNOWN;

    cmiAPIEnter(hApp, "cmChannelNew: hsCall=0x%p, haChan=0x%p, lphsChan=0x%p.", hsCall, haChan, lphsChan);
    if (emaLock((EMAElement)hsCall))
    {
        channel=allocateChannel(ctrl);
        if (!channel)
        {
            *lphsChan = NULL;
            emaUnlock((EMAElement)hsCall);
            cmiAPIExit(hApp, "cmChannelNew: [RESOURCE PROBLEM].");
            return RV_ERROR_OUTOFRESOURCES;
        }
        emaSetApplicationHandle((EMAElement)channel,(void*)haChan);
        channel->bOrigin=RV_TRUE;
        channel->hCtrl=ctrl;
        *lphsChan=(HCHAN)channel;
        emaUnlock((EMAElement)hsCall);
    }

    cmiAPIExit(hApp, "cmChannelNew: *lphsChan=0x%p [OK].", nprnd((int*)lphsChan));
    return 0;
}



RVAPI int RVCALLCONV
cmChannelGetCallHandles(
            /* Get the stack and application call handles by the channel handle */
            IN  HCHAN hsChan,
            OUT HCALL *hsCall,
            OUT HAPPCALL *haCall
            )
{
    H245Channel*channel=(H245Channel*)hsChan;
    HCONTROL ctrl;
    HCALL call;
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsChan);

    if (!hApp || !channel) return RV_ERROR_UNKNOWN;
    cmiAPIEnter(hApp, "cmChannelGetCallHandles:hsChan=0x%p",hsChan );

    if (emaLock((EMAElement)hsChan))
    {
        ctrl=(HCONTROL)channel->hCtrl;
        call=cmiGetByControl(ctrl);

        if (ctrl)
        {
            if (hsCall) *hsCall = call;
            if (haCall) *haCall = (HAPPCALL)emaGetApplicationHandle((EMAElement)call);
        }
        emaUnlock((EMAElement)hsChan);
    }

    cmiAPIExit(hApp, "cmChannelGetCallHandles:hsCall =0x%p",hsCall );
    return RV_TRUE;
}

RvBool channelTimeoutEventsHandler(void*hsChan)
{
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsChan);
    H245Channel*channel=(H245Channel*)hsChan;
    cmElem* app=(cmElem*)hApp;
    HPVT hVal;
    int message,nodeId;

    if (!hApp) return RV_FALSE;

    if (emaLock((EMAElement)hsChan))
    {
        hVal = ((cmElem *)hApp)->hVal;

        RvH323TimerClear(cmGetTimersHandle(hApp), &channel->pTimer);
        if (channel->eState!=ChannelStateReleased)
        {
            emaMark((EMAElement)hsChan);
            if (channel->eState==ChannelStateAwaitingEstablishment)
            {
                    message=pvtAddRoot(hVal,app->synProtH245,0,NULL);
                    nodeId=pvtAddBranch2(hVal,message, __h245(request),__h245(closeLogicalChannel));
                    pvtAdd(hVal,nodeId,__h245(forwardLogicalChannelNumber),channel->myLogicalChannelNum,NULL,NULL);
                    pvtAddBranch2(hVal,nodeId,__h245(source),__h245(lcse));

                    sendMessageH245(channel->hCtrl, message);
                    pvtDelete(hVal,message);
                    channel->eState=ChannelStateReleased;
                    {
                        void* ptr=NULL;
                        H245Channel* dependent;
                        while((dependent=getNextOutChanByBase(channel->hCtrl,channel,&ptr)))
                        {/* release the dependent channels because the base timed out */
                            if (dependent->eState!=ChannelStateReleased)
                            {
                                ptr=NULL;
                                emaLock((EMAElement)dependent);
                                emaUnlock((EMAElement)hsChan);
                                dependent->eState=ChannelStateReleased;
                                notifyChannelState(dependent,cmChannelStateDisconnected,cmChannelStateModeDisconnectedLocal);
                                notifyChannelState(dependent,cmChannelStateIdle, cmChannelStateModeOff);
                                emaLock((EMAElement)hsChan);
                                emaUnlock((EMAElement)dependent);
                            }
                        }
                    }
                    ((H245Control*)channel->hCtrl)->conflictChannels--;
            }
            channel->eState=ChannelStateReleased;
            notifyChannelState(channel,cmChannelStateDisconnected,cmChannelStateModeDisconnectedLocal);
            notifyChannelState(channel,cmChannelStateIdle, cmChannelStateModeOff);
            emaRelease((EMAElement)hsChan);
        }
        emaUnlock((EMAElement)hsChan);
    }
    return RV_FALSE;
}

RvBool channelRC_TimeoutEventsHandler(void*hsChan)
{
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsChan);
    H245Channel*channel=(H245Channel*)hsChan;
    HPVT hVal;
    int message,nodeId;
    cmElem*app=(cmElem*)hApp;
    int nesting;

    if (!hApp)   return RV_FALSE;

    if (emaLock((EMAElement)hsChan))
    {
        hVal = ((cmElem *)hApp)->hVal;

        RvH323TimerClear(cmGetTimersHandle(hApp), &channel->pRequestCloseTimer);

        message=pvtAddRoot(hVal,app->synProtH245,0,NULL);
        nodeId=pvtAddBranch2(hVal,message, __h245(indication),__h245(requestChannelCloseRelease));
        pvtAdd(hVal,nodeId,__h245(forwardLogicalChannelNumber),channel->myLogicalChannelNum,NULL,NULL);

        sendMessageH245(channel->hCtrl, message);
        pvtDelete(hVal,message);

        cmiCBEnter(hApp, "cmEvChannelRequestCloseStatus: haChan=0x%p, hsChan=0x%p, status=reject.",
                         (HAPPCHAN)emaGetApplicationHandle((EMAElement)channel), channel);
        nesting = emaPrepareForCallback((EMAElement)hsChan);
        ifE(app->cmMyChannelEvent.cmEvChannelRequestCloseStatus)((HAPPCHAN)emaGetApplicationHandle((EMAElement)channel), (HCHAN)channel, cmRequestCloseReject);
        emaReturnFromCallback((EMAElement)hsChan, nesting);
        emaUnlock((EMAElement)hsChan);
        cmiCBExit(hApp, "cmEvChannelRequestCloseStatus.");
    }
    return RV_FALSE;
}


/************************************************************************
 * startEstablishment
 * purpose: Start establishing a channel. This function creates an OLC
 *          message from the channel element and sends it.
 * input  : app     - Stack object
 *          channel - H245Channel element to send OLC for
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int startEstablishment(IN HAPP hApp, IN HCHAN hChan)
{
    cmElem* app = (cmElem *)hApp;
    H245Channel* channel = (H245Channel *)hChan;
    HPVT hVal=app->hVal;
    int ret;
    int message,olcID, forwardLCP_ID,reverseLCP_ID,h225ID,dataType,tmpID;

    /* Create an OLC message */
    message = pvtAddRoot(hVal,app->synProtH245,0,NULL);
    __pvtBuildByFieldIds(olcID, hVal, message, {_h245(request) _h245(openLogicalChannel) LAST_TOKEN}, 0, NULL);

    forwardLCP_ID = pvtAddBranch(hVal, olcID, __h245(forwardLogicalChannelParameters));

    /* Reverse data type. set only if we're in duplex mode.*/
    if (channel->bIsDuplex)
        reverseLCP_ID = pvtAddBranch(hVal, olcID, __h245(reverseLogicalChannelParameters));
    else
        reverseLCP_ID = RV_ERROR_UNKNOWN;

    /* Set the dataType of this channel */
    dataType = pvtAddBranch(hVal, forwardLCP_ID, __h245(dataType));
    ret = pvtSetTree(hVal, dataType, hVal, channel->dataTypeID);

    /* - H225 parameters start here */

⌨️ 快捷键说明

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