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

📄 faststart.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 4 页
字号:
 ************************************************************************/
RVAPI int RVCALLCONV
cmCallFastStartOpenChannels(
    IN HCALL    hsCall,
    IN int*     proposed,
    IN int*     accepted,
    IN RvBool   origin)
{
    callElem* call=(callElem*)hsCall;
    HPVT hVal;
    cmElem* app;
    int i;
    int ret = RV_OK;
    int rtcpAddressID[MAX_FS_SESSION_ID];
    int rtpAddressID[MAX_FS_SESSION_ID];
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
    if (!hApp) return RV_ERROR_UNKNOWN;
    app=(cmElem*)hApp;

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

    if ((call->fastStartState==fssAck) || (call->fastStartState==fssRej))
        return RV_ERROR_UNKNOWN;

    cmiAPIEnter(hApp, "cmCallFastStartOpenChannels(hsCall=0x%p)", hsCall);

    if (emaLock((EMAElement)hsCall))
    {
        hVal = app->hVal;

        memset(rtcpAddressID, 0xff, sizeof(rtcpAddressID));
        memset(rtpAddressID, 0xff, sizeof(rtpAddressID));

        /*Go through all proposed channels and collect RTCP addresses*/
        /*One RTCP address per sessionID*/
        for (i=0;proposed[i]>=0;i++)
        {
            int inReverseLCPNodeId,inForwardLCPNodeId;
            int inH2250ParametersNodeId;
            RvBool nullDataType;
            int sessionID;

            inReverseLCPNodeId=pvtGetChild(hVal, proposed[i], __h245(reverseLogicalChannelParameters),NULL);
            inForwardLCPNodeId=pvtGetChild(hVal, proposed[i], __h245(forwardLogicalChannelParameters),NULL);

            nullDataType=(pvtGetChild2(hVal, inForwardLCPNodeId, __h245(dataType),__h245(nullData))>=0);
            if (inReverseLCPNodeId >= 0)
                inH2250ParametersNodeId=pvtGetChild2(hVal, inReverseLCPNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));
            else
                inH2250ParametersNodeId=pvtGetChild2(hVal, inForwardLCPNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));

            if (pvtGetChildValue(hVal, inH2250ParametersNodeId,__h245(sessionID),&sessionID, NULL)>=0)
            {
                if (sessionID<=MAX_FS_SESSION_ID)
                {
                    /* We've got a session ID - find the remote's RTP and RTCP addresses for it */
                    if (rtcpAddressID[sessionID]<0)
                    {
                        int rtcpNodeID=pvtGetChild(hVal,inH2250ParametersNodeId,__h245(mediaControlChannel),NULL);
                        if (rtcpNodeID>=0)
                        {
                            rtcpAddressID[sessionID]=pvtAddRoot(hVal,app->hAddrSynH245,0,NULL);
                            pvtSetTree(hVal,rtcpAddressID[sessionID],hVal,rtcpNodeID);
                        }
                    }
                    if (rtpAddressID[sessionID]<0)
                    {
                        int rtpNodeID=pvtGetChild(hVal,inH2250ParametersNodeId,__h245(mediaChannel),NULL);
                        if (rtpNodeID>=0)
                        {
                            rtpAddressID[sessionID]=pvtAddRoot(hVal,app->hAddrSynH245,0,NULL);
                            pvtSetTree(hVal,rtpAddressID[sessionID],hVal,rtpNodeID);
                        }
                    }
                }
            }
        }

        /* Go through the list of accepted channels and open them locally */
        {
            RvBool controlReported = RV_FALSE;
            HCONTROL control;

            control = cmiGetControl((HCALL)call);
            call->fastStartState = fssAck;

            for (i=0;accepted[i]>=0;i++)
            {
                int inReverseLCPNodeId, inForwardLCPNodeId;
                int inLCPNodeId;
                RvBool nullDataType;
                H245Channel* channel;
                confDataType type = (confDataType)0;

                /* Allocate the channel */
                channel = allocateChannel(control);
                if (!channel)
                {
                    /* Don't continue... */
                    ret = RV_ERROR_OUTOFRESOURCES;
                    break;
                }
                channel->pChannelParams.data.h225Params.fastStartChannelIndex = i;

                if (!controlReported)
                {
                    /* Notify application, that the call is in cmControlStateFastStart */
                    cmiReportControl(hsCall,cmControlStateFastStart,(cmControlStateMode)0);

                    /* We only do that once, and only after we are sure we have a channel that
                       we'll open */
                    controlReported = RV_TRUE;
                }

                /* check the channel direction: only proposal for outgoing channels have reverse parameters*/
                inReverseLCPNodeId = pvtGetChild(hVal, accepted[i], __h245(reverseLogicalChannelParameters),NULL);
                inForwardLCPNodeId = pvtGetChild(hVal, accepted[i], __h245(forwardLogicalChannelParameters),NULL);

                nullDataType = (pvtGetChild2(hVal, inForwardLCPNodeId, __h245(dataType),__h245(nullData))>=0);

                if (nullDataType) /*Incoming channel*/
                    channel->bOrigin = (origin)?RV_FALSE:RV_TRUE;
                else
                    channel->bOrigin = (origin)?RV_TRUE:RV_FALSE;

                /* Check if this channel is a duplex channel */
                if (inReverseLCPNodeId>=0 &&
                    inForwardLCPNodeId>=0 && !nullDataType)
                    channel->bIsDuplex=RV_TRUE;

                /* Get the logical channel number */
                pvtGetChildValue(hVal, accepted[i], __h245(forwardLogicalChannelNumber),&(channel->myLogicalChannelNum), NULL);
                if (channel->bIsDuplex)
                    channel->reverseLogicalChannelNum = channel->myLogicalChannelNum;

                if (inForwardLCPNodeId >= 0)
                    pvtGetChildValue(hVal,inForwardLCPNodeId,__h245(portNumber),&channel->remotePortNumber,NULL);

                inLCPNodeId=(inReverseLCPNodeId>=0)?inReverseLCPNodeId:inForwardLCPNodeId;

                if (inLCPNodeId >= 0)
                {
                    /* Now that we're in the right parameters for this channel -
                       let's get down to the business of opening this channel for the application */
                    int inDataTypeId;
                    int tmpNodeId;

                    /* Get the dataType of this channel and store it */
                    inDataTypeId=pvtGetChild(hVal, inLCPNodeId,__h245(dataType),NULL);
                    channel->dataTypeID=pvtAddRoot(hVal,app->h245DataType,0,NULL);
                    pvtSetTree(hVal,channel->dataTypeID,hVal, inDataTypeId);

                    /* Get the session ID of this channel */
                    __pvtGetByFieldIds(tmpNodeId, hVal, inLCPNodeId,
                        {_h245(multiplexParameters) _h245(h2250LogicalChannelParameters) _h245(sessionID) LAST_TOKEN}, NULL, &channel->sessionId, NULL);

                    if ((channel->sessionId > 0) && (channel->sessionId <= MAX_FS_SESSION_ID))
                    {
                        int* addrNodeId;

                        /* Get the proposed RTP and RTCP addresses for this channel, and
                           insert them into the channel object */
                        if (rtpAddressID[channel->sessionId] >= 0)
                        {
                            if (origin) addrNodeId = &channel->pChannelParams.data.h225Params.recvRtpAddressID;
                            else        addrNodeId = &channel->pChannelParams.data.h225Params.sendRtpAddressID;
                            if ((*addrNodeId) < 0) *addrNodeId = pvtAddRoot(hVal, app->hAddrSynH245, 0, NULL);
                            pvtSetTree(hVal, *addrNodeId, hVal, rtpAddressID[channel->sessionId]);
                        }
                        if (rtcpAddressID[channel->sessionId] >= 0)
                        {
                            if (origin) addrNodeId = &channel->pChannelParams.data.h225Params.recvRtcpAddressID;
                            else        addrNodeId = &channel->pChannelParams.data.h225Params.sendRtcpAddressID;
                            if ((*addrNodeId) < 0) *addrNodeId = pvtAddRoot(hVal, app->hAddrSynH245, 0, NULL);
                            pvtSetTree(hVal, *addrNodeId, hVal, rtcpAddressID[channel->sessionId]);
                        }
                    }

                    /* Find a partner for this channel if there is one */
                    if (channel->bOrigin)
                        channel->pPartner = getInChanBySID(control, channel->sessionId);
                    else
                        channel->pPartner = getOutChanBySID(control, channel->sessionId);
                    if (channel->pPartner != NULL)
                    {
                        /* Link it the other way around as well. No need to lock the second
                           channel, since the channels are locked by their call already */
                        channel->pPartner->pPartner = channel;
                    }


                    /* Lock this channel - we're about to make callbacks in this place */
                    if(emaLock((EMAElement)channel))
                    {
                        if (app->cmMySessionEvent.cmEvCallNewChannel)
                        {
                            HAPPCALL haCall = emaGetApplicationHandle((EMAElement)call);
                            HAPPCHAN haChan = NULL;
                            int nesting;

                            cmiCBEnter(hApp, "cmEvCallNewChannel:%s: haCall=0x%p, hsCall=0x%p. hsChan=0x%p",
                                (channel->bOrigin ? "OUT" : "IN"), haCall, call, channel);

                            nesting = emaPrepareForCallback((EMAElement)channel);
                            app->cmMySessionEvent.cmEvCallNewChannel(haCall, (HCALL)call, (HCHAN)channel, &haChan);
                            emaSetApplicationHandle((EMAElement)channel, (void*)haChan);
                            emaReturnFromCallback((EMAElement)channel, nesting);

                            cmiCBExit(hApp, "cmEvCallNewChannel:%s: haChan=0x%p.",
                                (channel->bOrigin ? "OUT" : "IN"), haChan);
                        }

                        if (!emaWasDeleted((EMAElement)channel))
                        {
                            /* Update the MIB with this new channel */
                            if (app->mibEvent.h341AddNewLogicalChannel)
                                app->mibEvent.h341AddNewLogicalChannel(app->mibHandle, (HCHAN)channel);

                            /* Call channel parameters callback if needed */
                            cmcCallChannelParametersCallback((HAPP)app, (HCHAN)channel, channel->dataTypeID, &type);
                        }

                        if (!emaWasDeleted((EMAElement)channel))
                        {
                            /* Now call the dataType callback if we still have this channel */
                            cmcCallDataTypeHandleCallback((HAPP)app, (HCHAN)channel, channel->dataTypeID, type);
                        }

                        if (!emaWasDeleted((EMAElement)channel))
                        {
                            /* Get the session ID of this channel and the node of the parameters -
                            we'll need it later for RTP and RTCP addresses */

                            /* Find the nodeId of the logical channel parameters from the
                            proposed part of the call - we want to notify the application
                            about the remote's RTP and RTCP addresses */
                            int paramsNodeId;

                            if (!origin)
                            {
                                /* This means we're the side that should send the CONNECT - we want the
                                proposed nodeId */
                                paramsNodeId = pvtGetChild(hVal, proposed[i], __h245(reverseLogicalChannelParameters), NULL);
                                if (paramsNodeId < 0)
                                    paramsNodeId = pvtGetChild(hVal, proposed[i], __h245(forwardLogicalChannelParameters), NULL);
                            }
                            else
                            {
                                /* This means we're the side that received the CONNECT. We already have the parameters
                                node id in inLCPNodeId. */
                                paramsNodeId = inLCPNodeId;
                            }

                            /* Now let's find the parameters... */
                            __pvtGetNodeIdByFieldIds(paramsNodeId, hVal, paramsNodeId, {_h245(multiplexParameters) _h245(h2250LogicalChannelParameters) LAST_TOKEN});

                            /* Notify the application about the remote's RTP and RTCP addresses */
                            cmcCallAddressCallbacks(app, channel, paramsNodeId, origin);
                        }

                        if (!emaWasDeleted((EMAElement)channel))
                        {
                            /* Now that we're done - notify the state of this channel is connected */
                            channel->eState = ChannelStateEstablished;
                            notifyChannelState(channel,cmChannelStateConnected,cmChannelStateModeOn);
                        }

                        /* We're done with all the callbacks for this channel - unlock it */
                        emaUnlock((EMAElement)channel);
                    }

                    /* If someone deleted this call, we should get out of this for loop */
                    if (emaWasDeleted((EMAElement)hsCall))
                        break;
                }
            }
        }

        /* No need for the addresses anymore - delete them */
        for (i = 0; i < MAX_FS_SESSION_ID; i++)
        {
            if (rtcpAddressID[i] >= 0)
                pvtDelete(hVal, rtcpAddressID[i]);
            if (rtpAddressID[i] >= 0)
                pvtDelete(hVal, rtpAddressID[i]);
        }

        emaUnlock((EMAElement)hsCall);
    }

    cmiAPIExit(hApp, "cmCallFastStartOpenChannels: [%d]", ret);
    return ret;
}


int fastStartInit(IN cmElem* app, IN int maxCalls, IN int proposed, IN int accepted)
{
    RvLogSourceConstruct(RvLogGet(), &app->logFastStart, RV_LOG_LIBCODE_H323, "FASTSTART", "Fast Start Messages");

    /* Allocate the buffer of fast start nodes */
    /* add one to values, last in array must be -1 */
    RvMemoryAlloc(NULL, (void**)&app->fastStartBuff, (RvSize_t)maxCalls*(proposed+accepted+2)*sizeof(int));
    RvMemoryAlloc(NULL, (void**)&app->fastStartBuff2, (RvSize_t)maxCalls*(accepted+1)*sizeof(RvUint8));

    /* Set the values in the stack's instance */
    app->maxFsProposed=proposed;
    app->maxFsAccepted=accepted;

    return ((app->fastStartBuff != NULL)&&(app->fastStartBuff2 != NULL));
}


void fastStartEnd(IN cmElem* app)
{
    if (app->fastStartBuff)
        RvMemoryFree(app->fastStartBuff);
    if (app->fastStartBuff2)
        RvMemoryFree(app->fastStartBuff2);
    RvLogSourceDestruct(RvLogGet(), &app->logFastStart);
}


void fastStartCallInit(IN callElem* call)
{
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
    int callNumber;

    /* Set initial fast start values of the call */
    call->fastStartState=fssNo;
    call->fastStartNodesCount=0;
    call->fastStartNodesAckCount=0;
    call->lcnOut=0;

    /* Find out the call's index: We'll use that to access it's fast start channels */
    callNumber = emaGetIndex((EMAElement)call);

    /* Set the pointers to the right places inside the fast start buffer */
    call->fastStartNodes =
        app->fastStartBuff + (callNumber * (app->maxFsProposed + app->maxFsAccepted + 2));
    call->fastStartNodesAck = call->fastStartNodes + app->maxFsProposed + 1;
    call->fastStartIndexes = app->fastStartBuff2 + (callNumber * (app->maxFsAccepted + 1));

    /* Clear the nodes to -1 */
    memset(call->fastStartNodes, 0xff, (RvSize_t)sizeof(int)*(app->maxFsProposed + app->maxFsAccepted + 2));
    memset(call->fastStartIndexes, 0xff, (RvSize_t)sizeof(RvUint8)*(app->maxFsAccepted + 1));
}



#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

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