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

📄 faststart.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 4 页
字号:
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
RVAPI int RVCALLCONV
cmFastStartGet(
        IN  HCALL               hsCall,
        IN  int                 fsChannelId,
        OUT cmCapDataType*      type,
        OUT cmChannelDirection* direction,
        OUT cmFastStartChannel* fsChannel)
{
    callElem* call=(callElem*)hsCall;
    int dirNodeId,paramNodeId,tempNodeId, sid;
    HAPP hApp;
    HPVT hVal;

    if (!hsCall) return RV_ERROR_UNKNOWN;
    hApp=(HAPP)emaGetInstance((EMAElement)call);
    if (!hApp) return RV_ERROR_UNKNOWN;

    cmiAPIEnter(hApp, "cmFastStartGet: hsCall=0x%p",hsCall);
    if (emaLock((EMAElement)hsCall))
    {
        hVal = ((cmElem *)hApp)->hVal;

        /* Get the reverse part of the OLC message to determine whether it is
         a receiving channel or a transmitting channel (from the viewpoint of
         the remote that sent the SETUP) */
        dirNodeId=pvtGetChild(hVal, fsChannelId, __h245(reverseLogicalChannelParameters),NULL);

        {
            /* in or bidirectional channel */
            /* Get the forward parameters */
            int tmpNodeId=pvtGetChild(hVal, fsChannelId,__h245(forwardLogicalChannelParameters),NULL);
            if (pvtGetChild2(hVal, tmpNodeId, __h245(dataType),__h245(nullData))<0)
            {                        /* Forward DataType is OK */
                if (dirNodeId >= 0) /* and there are reverse parameters */
                {   /* bidirectional channel */
                  if (direction)
                        *direction=dirBoth;
                }
                else                /* no reverse parameters */
                {
                    /* in channel */
                    dirNodeId = tmpNodeId;
                    if (direction)
                        *direction=dirReceive;
                }
            }
            else                    /* no forward DataType */
            {   /* out channel */

              if (direction)
                    *direction=dirTransmit;
            }
        }

        /* Get the H2550 parameters of the channel */
        paramNodeId = pvtGetChild2(hVal, dirNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));

        sid = 0;

        /* according to the dataType determine if it's an Audio or a Video
         channel and set the session Id accordingly.
         Note: This part needs to be enhanced for support of other types (data, fax etc.)*/

        tempNodeId = pvtChild(hVal,pvtGetChild(hVal, dirNodeId, __h245(dataType),NULL));
        {
          static char const SID_From_Index[]={0,0,0,2,1,3,0,0,0};
          int index=pvtGetSyntaxIndex(hVal,tempNodeId);
          if (index>=0)
            sid=SID_From_Index[index];
        }

        if (type)
            *type=(cmCapDataType)sid;

        /* set the pvt of the dataType subtree */
        fsChannel->dataTypeHandle=pvtGetChild(hVal, dirNodeId, __h245(dataType),NULL);


        /* Get the codec type name and fill it into the table */
        {
            int capNodeId;
            RvPstFieldId fieldId;

            /* For Data capabilities, we have to go one step further... */
            capNodeId = pvtChild(hVal, pvtChild(hVal, fsChannel->dataTypeHandle));
            if ((cmCapDataType)sid == cmCapData)
                capNodeId = pvtChild(hVal, capNodeId);

            pvtGet(hVal, capNodeId, &fieldId,NULL,NULL,NULL);
            fsChannel->channelName = pstGetFieldNamePtr(pvtGetSynTree(hVal, dirNodeId),fieldId);
        }

        /* Get the rtcp ip address and fill that into the table */
        cmVtToTA_H245(hVal,pvtGetChild(hVal,paramNodeId, __h245(mediaControlChannel), NULL) , &fsChannel->rtcp);

        /* Get the rtp ip address and fill that into the table */
        cmVtToTA_H245(hVal,pvtGetChild(hVal,paramNodeId, __h245(mediaChannel), NULL) , &fsChannel->rtp);

        /* We have no way of knowing the channel index when we are here, so we'll just put in with -1 */
        fsChannel->index = -1;

        emaUnlock((EMAElement)hsCall);
    }

    cmiAPIExit(hApp, "cmFastStartGet: [0]");
    return 0;
}


/******************************************************************************************
 * analyzeFastStartMsg
 *
 * Purpose:  This function is called upon receipt of a setup message.
 *           The function checks for any fast-start channels in the message,
 *           decodes the data and builds it into a structure that is passed in a CallBack
 *           to the application, such that the application may ack some of them.
 *
 * Input:    call       - call object instance
 *           message    - The node id to the setup message
 *
 * Reurned Value: Non-negative value on success
 *                Negative value on failure
 ****************************************************************************************/
int
analyzeFastStartMsg(
                IN  callElem*       call,
                IN  int             message)
{
    cmFastStartMessage fsMessage;
    int nodeId;
    int nesting;

    RvUint8 lcnAllocationBuff[(MAX_FASTSTART_CHANNELS+1)/sizeof(char)];

    int decoded_length, buff_len, freeLoc=0;
    int index=0;
    int typeLoc[MAX_FS_CHANNELS+1];
    int encodedOctedStrings;
    cmAlternativeChannels *pAltChannel;
    HPVT hVal;
    HAPP hApp=(HAPP)emaGetInstance((EMAElement)call);
    cmElem* app=(cmElem*)hApp;

    if (!app->cmMyCallEvent.cmEvCallFastStartSetup && !app->cmMyCallEvent.cmEvCallFastStart) return RV_TRUE;
    if ((call->fastStartState==fssAck) || (call->fastStartState==fssRej))   return RV_TRUE;
    hVal=app->hVal;

    /* Find out if we've got faststart at all in this message */
    __pvtGetNodeIdByFieldIds(encodedOctedStrings,hVal,message,
                        {_q931(message)
                         _anyField
                         _q931(userUser)
                         _q931(h323_UserInformation)
                         _q931(h323_uu_pdu)
                         _q931(h323_message_body)
                         _anyField
                         _q931(fastStart)
                         LAST_TOKEN});
    if (encodedOctedStrings<0) return RV_ERROR_UNKNOWN;
    call->fastStartState=fssRequest;

    /* Initialized the table to be built */
    memset(&fsMessage,0,sizeof(cmFastStartMessage));
    memset(typeLoc,0xff,sizeof(typeLoc));
    memset(lcnAllocationBuff,0,sizeof(lcnAllocationBuff));

    /* Go over the received encoded OLC message from the SETUP,
       decode them for subsequent analysis */
    nodeId = pvtChild(hVal, encodedOctedStrings);
    while (nodeId > 0)
    {
        RvUint8* encodeBuffer;

        /* Get a buffer to work with */
        getEncodeDecodeBuffer(app->encodeBufferSize, &encodeBuffer);
        if (encodeBuffer != NULL)
        {
            buff_len = pvtGetString(hVal, nodeId, app->encodeBufferSize, (char*)encodeBuffer);
        }
        else
            buff_len = -1; /* Make sure we don't continue */

        if (buff_len > 0)
        {
            /* Decode an OpenLogicalChannel faststart message */
            int decodingResult;
            int chanMsgId=call->fastStartNodes[index]=pvtAddRoot(hVal, app->synOLC, 0, NULL);
            call->fastStartNodesCount++;

            decodingResult = cmEmDecode(hVal, chanMsgId, encodeBuffer, buff_len, &decoded_length);
            if (decodingResult < 0)
                chanMsgId = -1;

            RvH323CmPrintMessage(&app->logFastStart, "Suggested faststart channel decoded:",
                hVal, chanMsgId, encodeBuffer, decoded_length, RV_TRUE);

            if (decodingResult >= 0)
            {
                /* Make the logical channel's number as taken */
                int lcn;
                pvtGetChildValue(hVal, chanMsgId,__h245(forwardLogicalChannelNumber),&lcn,NULL);
                setBitTrue(lcnAllocationBuff,lcn/MAX_LCN_S);
            }
            else
            {
                /* Got an error - try next fs proposal */
                nodeId = pvtBrother(hVal, nodeId);
                continue;
            }

            if (app->cmMyCallEvent.cmEvCallFastStartSetup)
            {
                cmFastStartChannel fsChannel;
                cmCapDataType type;
                cmChannelDirection direction;
                int loc;

                /* We now have an offered channel */
                /* Go over the OLC message and analyse it */

                cmFastStartGet((HCALL)call, chanMsgId, &type, &direction, &fsChannel);

                /* Fill the session Id into the channel table being prepared for the user */
                if (typeLoc[(int)type] == -1)
                {
                    loc=typeLoc[(int)type] = freeLoc++; /* todo: How is freeLoc used? */
                    fsMessage.partnerChannels[loc].type = type;
                    fsMessage.partnerChannelsNum++;
                }
                else
                    loc=typeLoc[(int)type];

                /* Set a pointer to the right part of the channel tables
                 according to the channels direction */
                if (direction==dirTransmit)
                                    pAltChannel    = &(fsMessage.partnerChannels[loc].transmit);
                else                pAltChannel    = &(fsMessage.partnerChannels[loc].receive);


                /* Now fill all the data from the OLC message to the table */
                if (pAltChannel->altChannelNumber < MAX_ALTERNATIVE_CHANNEL)
                {

                    /* Give the channel an index */
                    fsChannel.index = index;

                    pAltChannel->channels[pAltChannel->altChannelNumber]=fsChannel;

                    /* Advance the channels counter in the table */
                    pAltChannel->altChannelNumber++;

                }
            }
        }
        nodeId = pvtBrother(hVal, nodeId);
        index++;
        if (index == app->maxFsProposed)
        {
            /* we were offered more channels than we have room for - ignore the rest */
            /* array is maxFsProposed+1 size, must leave the last one -1 */
            break;
        }
    }
    /*If the number of fast start proposals was less then MAX_FASTSTART_CHANNELS then at least one range will be available */
    call->lcnOut=get1st0BitNumber(lcnAllocationBuff, 0, MAX_FASTSTART_CHANNELS)*MAX_LCN_S;

    if (app->cmMyCallEvent.cmEvCallFastStartSetup)
    {
        /* We call the callback with the table and supply it to the user.
         The user is supposed to acke the desired channels from that callback */
        cmiCBEnter(hApp,(char*)"cmEvCallFastStartSetup(haCall=0x%p,hsCall=0x%p)",(HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
        nesting=emaPrepareForCallback((EMAElement)call);
        app->cmMyCallEvent.cmEvCallFastStartSetup((HAPPCALL)emaGetApplicationHandle((EMAElement)call), (HCALL)call,&fsMessage);
        emaReturnFromCallback((EMAElement)call,nesting);
        cmiCBExit(hApp,(char*)"cmEvCallFastStartSetup");
    }

    if (!emaWasDeleted((EMAElement)call) && app->cmMyCallEvent.cmEvCallFastStart)
    {
        cmiCBEnter(hApp,(char*)"cmEvCallFastStart(haCall=0x%p,hsCall=0x%p)",(HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
        nesting=emaPrepareForCallback((EMAElement)call);
        app->cmMyCallEvent.cmEvCallFastStart((HAPPCALL)emaGetApplicationHandle((EMAElement)call), (HCALL)call);
        emaReturnFromCallback((EMAElement)call,nesting);
        cmiCBExit(hApp,(char*)"cmEvCallFastStart");
    }

    return  RV_TRUE;
}


RVAPI int RVCALLCONV
cmFastStartChannelsAckIndex(
    IN HCALL                hsCall,
    IN int                  index,
    IN cmTransportAddress*  rtcp,
    IN cmTransportAddress*  rtp)
{
    int ret = -1;
    int lcpNodeId;
    int h2250ParametersNodeId;
    int outOLCNodeId;
    callElem* call=(callElem*)hsCall;
    HAPP hApp;
    HPVT hVal;
    cmElem* app;
    if (!hsCall) return RV_ERROR_UNKNOWN;
    hApp=(HAPP)emaGetInstance((EMAElement)call);
    if (!hApp) return RV_ERROR_UNKNOWN;
    app=(cmElem*)hApp;
    hVal = app->hVal;

    cmiAPIEnter(hApp, "cmFastStartChannelsAckIndex: hsCall=0x%p,index = %d",hsCall,index);

    if (call->fastStartNodesAckCount == app->maxFsAccepted)
    {
        /* array is maxFsAccepted+1 size, must leave the last one -1 */
        cmiAPIExit(hApp, "cmFastStartChannelsAckIndex: out of room [-1]");
        return RV_ERROR_OUTOFRANGE;
    }

    if (emaLock((EMAElement)hsCall))
    {

        /* Start build OLC for ack */
        outOLCNodeId = pvtAddRoot(hVal, app->synOLC, 0, NULL);

        if (outOLCNodeId >= 0)
        {
            call->fastStartIndexes[call->fastStartNodesAckCount] = (RvUint8) index;
            call->fastStartNodesAck[call->fastStartNodesAckCount++] = outOLCNodeId;

            /* Copy the OLC*/
            pvtSetTree(hVal,outOLCNodeId, hVal, call->fastStartNodes[index]);

            /* check the channel direction, only proposal for outgoing and bi-directional channels have reverse parameters*/
            lcpNodeId=pvtGetChild(hVal, outOLCNodeId, __h245(reverseLogicalChannelParameters),NULL);

            if (lcpNodeId >= 0)
            {
                /* For outgoing channel do: */
                /* Overwrite the fwd LCN */
                pvtAdd(hVal, outOLCNodeId, __h245(forwardLogicalChannelNumber),++call->lcnOut, NULL,NULL);
            }
            else
                lcpNodeId=pvtGetChild(hVal, outOLCNodeId, __h245(forwardLogicalChannelParameters),NULL);

            h2250ParametersNodeId=pvtGetChild2(hVal, lcpNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));

            if (h2250ParametersNodeId>=0)
            {
                int tmpNodeId;
                tmpNodeId = pvtAddBranch(hVal, h2250ParametersNodeId, __h245(mediaChannel));
                if ((rtp != NULL) && (rtp->ip || rtp->port))

⌨️ 快捷键说明

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