cmpreservation.c

来自「基于h323协议的软phone」· C语言 代码 · 共 1,152 行 · 第 1/3 页

C
1,152
字号
            {
                /* call was already activated. big error. */
                return RV_ERROR_UNKNOWN;
            }
            isNewCall = RV_FALSE;
            /* remove the previous control */
            ctrl = (H245Control *) cmiGetControl((HCALL)newCall);
            if(ctrl->outCap.termNodeId >= 0)
            {
                pvtDelete(app->hVal, ctrl->outCap.termNodeId);
            }
            if(ctrl->inCap.termNodeId >= 0)
            {
                pvtDelete(app->hVal, ctrl->inCap.termNodeId);
            }
            /* remove the previous property */
            if(newCall->property >= 0)
            {
                pvtDelete(app->hVal, newCall->property);
            }
            /* remove the previous session */
            if(newCall->hsTransSession)
            {
                emaDelete((EMAElement)newCall->hsTransSession);
            }
            /* remove the previous channels */
            nextChan = curChan = (H245Channel *) cmiGetChannelListForCall((HCALL)newCall);
            while(nextChan != NULL)
            {
                nextChan = curChan->pNext;
                emaDelete(curChan);
            }
            break;
        }
    }
    if(newCall == NULL)
    {
        /* if no call yet, get a new call from the EMA */
        newCall = (callElem *)emaAdd(app->hCalls,(void*)haCall);
        if (!newCall)
        {
            /* no calls in EMA - exit */
            return RV_ERROR_UNKNOWN;
        }
    }
    /* copy the preserved call into the new Call */
    memcpy((void*)newCall,(void*)&call,sizeof(callElem));
    emaSetApplicationHandle((EMAElement) newCall, (void*) haCall);
    m_callset(newCall,preservedCall,RV_TRUE);

    /* now get the preserved control element */
    if((length-lenDone) >= sizeof(H245Control))
        memcpy((void*)&control, (void*)(buffer+lenDone), sizeof(H245Control));
    else
    {
        emaDelete((EMAElement)newCall);
        return RV_ERROR_UNKNOWN;
    }
    lenDone += sizeof(H245Control);
    /* rebuild the capabilities, if needed */
    if(control.outCap.termNodeId >= 0)
    {
        if(decodeFromBuffer(app->hVal, NULL, &control.outCap.termNodeId, buffer, length, &lenDone) < 0)
        {
            emaDelete((EMAElement)newCall);
            return RV_ERROR_UNKNOWN;
        }
    }
    if(control.inCap.termNodeId >= 0)
    {
        if(decodeFromBuffer(app->hVal, NULL, &control.inCap.termNodeId, buffer, length, &lenDone) < 0)
        {
            pvtDelete(app->hVal, control.outCap.termNodeId);
            emaDelete((EMAElement)newCall);
            return RV_ERROR_UNKNOWN;
        }
    }
    /* set the timers to NULL */
    control.outCap.timer = NULL;
    control.msd.timer = NULL;
    control.roundTrip.timer = NULL;
    control.outRequestMode.timer = NULL;
    /* copy into the control element */
    newControl = (H245Control *) cmiGetControl((HCALL)newCall);
    memcpy((void*)newControl, (void*)&control, sizeof(H245Control));

    /* Get the session, if needed */
    if(call.hsTransSession)
    {
        if((length-lenDone) >= sizeof(cmTransSession))
            memcpy((void*)&session, (void*)(buffer+lenDone), sizeof(cmTransSession));
        else
        {
            pvtDelete(app->hVal, control.inCap.termNodeId);
            pvtDelete(app->hVal, control.outCap.termNodeId);
            emaDelete((EMAElement)newCall);
            return RV_ERROR_UNKNOWN;
        }
        lenDone += sizeof(cmTransSession);
    }

    /* decode the property, if needed*/
    if(call.property >= 0)
    {
        if(decodeFromBuffer(app->hVal, app->hSyn, &property, buffer, length, &lenDone) < 0)
        {
            pvtDelete(app->hVal, control.inCap.termNodeId);
            pvtDelete(app->hVal, control.outCap.termNodeId);
            emaDelete((EMAElement)newCall);
            return RV_ERROR_UNKNOWN;
        }
    }
    newCall->property = property;

    {
        int t303, t304, t301;
        /* Get the timeout values for call setup related timeouts */
        pvtGet(app->hVal,pvtGetChild(app->hVal,app->q931Conf,__q931(connectTimeOut), NULL),NULL,NULL,&t301,NULL);
        t301*=1000;
        if(isNewCall)
        {
            pvtGet(app->hVal,pvtGetChild(app->hVal,app->q931Conf,__q931(responseTimeOut),NULL),NULL,NULL,&t304,NULL);
            t303=t304*1000;
            pvtGet(app->hVal,pvtGetChild(app->hVal,app->q931Conf,__q931(t304),NULL),NULL,NULL,&t304,NULL);
            t304*=1000;

            /* Create the Q931 "object" of the call */
            q931CallCreate((HQ931)cmiGetQ931((HCALL)newCall), t301, -1, t303, t304, t301, 100000);
        }

        /* See if the call has timers */
        if(newCall->timer)
        {
            /* check the call state to see if a timer should be set */
            if( (newCall->state == cmCallStateDialtone) ||
                (newCall->state == cmCallStateProceeding) ||
                (newCall->state == cmCallStateRingBack) ||
                (newCall->state == cmCallStateOffering) ||
                (newCall->state == cmCallStateOffering) ||
                (newCall->state == cmCallStateTransfering) ||
                (newCall->state == cmCallStateIncompleteAddress) ||
                (newCall->state == cmCallStateWaitAddressAck) )
            {
                /* set a connect timer for disconnection */
                newCall->timer = RvH323TimerStart(cmGetTimersHandle(hApp),q931T301Timeout,(void*)cmiGetQ931((HCALL)newCall),t301*1000);
            }
        }
    }

    /* add the new session to the call */
    if(newCall->hsTransSession)
    {
        newSession = emaAdd(transGlobals->hEmaSessions, (void*)newCall);

        if(!newSession)
        {
            pvtDelete(app->hVal, property);
            pvtDelete(app->hVal, control.inCap.termNodeId);
            pvtDelete(app->hVal, control.outCap.termNodeId);
            emaDelete((EMAElement)newCall);
            return RV_ERROR_UNKNOWN;
        }

        newCall->hsTransSession = (HSTRANSSESSION) newSession;
        memcpy((void*)newSession, (void*)&session, sizeof(cmTransSession));

        /* set a few session parameters */
        if(newSession->Q931Connection)   newSession->Q931Connection =   (cmTransHost*)0xffffffff;
        if(newSession->annexEConnection) newSession->annexEConnection = (cmTransHost*)0xffffffff;
        if(newSession->H245Connection)   newSession->H245Connection =   (cmTransHost*)0xffffffff;
        newSession->nextPending = NULL;
        newSession->prevPending = NULL;
        newSession->nextSession = NULL;
        newSession->prevSession = NULL;
    }

    /* now for the channels */
    if(lenDone < length)
    {
        memcpy((void*)&chanArraySize, (void*)(buffer+lenDone), sizeof(int));
        lenDone += sizeof(int);
        /* see if this call has channels */
        if(chanArraySize > 0)
        {
            memcpy((void*)chanPtrArray, (void*)(buffer+lenDone+sizeof(int)), chanArraySize*sizeof(H245Channel *));
            lenDone += chanArraySize*sizeof(H245Channel *);
            memcpy((void*)chanArray, (void*)(buffer+lenDone), chanArraySize*sizeof(H245Channel));
            lenDone += chanArraySize*sizeof(H245Channel);
        }
    }

    /* create the channel referance array */
    for(i=0; i<(int)chanArraySize; i++)
    {
        int j;

        newChannelArray[i] = (H245Channel *)emaAdd(app->hChannels, NULL);
        if (newChannelArray[i])
        {
            memcpy((void*)newChannelArray[i], (void*)&chanArray[i], sizeof(H245Channel));
            if (((newChannelArray[i]->pChannelParams.data.h225Params.redEncID < 0)        || (decodeFromBuffer(app->hVal, app->h245RedEnc, &newChannelArray[i]->pChannelParams.data.h225Params.redEncID, buffer, length, &lenDone) >= 0))   &&
                ((newChannelArray[i]->pChannelParams.data.h225Params.transCapID < 0)      || (decodeFromBuffer(app->hVal, app->h245TransCap, &newChannelArray[i]->pChannelParams.data.h225Params.transCapID, buffer, length, &lenDone) >= 0)) &&
                ((newChannelArray[i]->requestCloseParamID < 0)      || (decodeFromBuffer(app->hVal, app->h245DataType, &newChannelArray[i]->requestCloseParamID, buffer, length, &lenDone) >= 0)) &&
                ((newChannelArray[i]->dataTypeID < 0)      || (decodeFromBuffer(app->hVal, app->h245DataType, &newChannelArray[i]->dataTypeID, buffer, length, &lenDone) >= 0)) &&
                ((newChannelArray[i]->pChannelParams.data.h225Params.separateStackID < 0) || (decodeFromBuffer(app->hVal, app->h245DataType, &newChannelArray[i]->pChannelParams.data.h225Params.separateStackID, buffer, length, &lenDone) >= 0)))
            {
                /* all ok, skip the deleting process */
                continue;
            }
            /* if we are here, we must delete this channel... */
            pvtDelete(app->hVal, newChannelArray[i]->pChannelParams.data.h225Params.redEncID);
            pvtDelete(app->hVal, newChannelArray[i]->pChannelParams.data.h225Params.transCapID);
            pvtDelete(app->hVal, newChannelArray[i]->requestCloseParamID);
            pvtDelete(app->hVal, newChannelArray[i]->dataTypeID);
            pvtDelete(app->hVal, newChannelArray[i]->pChannelParams.data.h225Params.separateStackID);
            emaDelete((EMAElement)newChannelArray[i]);
        }
        /* ...and all those before it... */
        for(j=0; j < i; j++)
        {
            pvtDelete(app->hVal, newChannelArray[j]->pChannelParams.data.h225Params.redEncID);
            pvtDelete(app->hVal, newChannelArray[j]->pChannelParams.data.h225Params.transCapID);
            pvtDelete(app->hVal, newChannelArray[j]->requestCloseParamID);
            pvtDelete(app->hVal, newChannelArray[j]->dataTypeID);
            pvtDelete(app->hVal, newChannelArray[j]->pChannelParams.data.h225Params.separateStackID);
            emaDelete((EMAElement)newChannelArray[j]);
        }
        /* ...and the call itself */
        emaDelete((EMAElement)newSession);
        pvtDelete(app->hVal, property);
        pvtDelete(app->hVal, control.inCap.termNodeId);
        pvtDelete(app->hVal, control.outCap.termNodeId);
        emaDelete((EMAElement)newCall);
        return RV_ERROR_UNKNOWN;
    }

    /* set the channel pointers to the correct chanels */
    for(i=0; i<(int)chanArraySize; i++)
    {
        if(newChannelArray[i]->pPartner)
        {
            for(j=0; j<(int)chanArraySize; j++)
            {
                if(chanPtrArray[j] == newChannelArray[i]->pPartner)
                {
                    newChannelArray[i]->pPartner = newChannelArray[j];
                    break;
                }
            }
            if(j==(int)chanArraySize)
                newChannelArray[i]->pPartner = NULL;
        }

        if(newChannelArray[i]->pBase)
        {
            for(j=0; j<(int)chanArraySize; j++)
            {
                if(chanPtrArray[j] == newChannelArray[i]->pBase)
                {
                    newChannelArray[i]->pBase = newChannelArray[j];
                    break;
                }
            }
            if(j==(int)chanArraySize)
                newChannelArray[i]->pBase = NULL;
        }

        if(newChannelArray[i]->pAssociated)
        {
            for(j=0; j<(int)chanArraySize; j++)
            {
                if(chanPtrArray[j] == newChannelArray[i]->pAssociated)
                {
                    newChannelArray[i]->pAssociated = newChannelArray[j];
                    break;
                }
            }
            if(j==(int)chanArraySize)
                newChannelArray[i]->pAssociated = NULL;
        }

        if(newChannelArray[i]->pReplacementCh)
        {
            for(j=0; j<(int)chanArraySize; j++)
            {
                if(chanPtrArray[j] == newChannelArray[i]->pReplacementCh)
                {
                    newChannelArray[i]->pReplacementCh = newChannelArray[j];
                    break;
                }
            }
            if(j==(int)chanArraySize)
                newChannelArray[i]->pReplacementCh = NULL;
        }

        if(i==0) newChannelArray[i]->pPrev = NULL;
        else newChannelArray[i]->pPrev = newChannelArray[i-1];
        if(i==(int)chanArraySize) newChannelArray[i]->pNext = NULL;
        else newChannelArray[i]->pNext = newChannelArray[i+1];

        if(newChannelArray[i]->pTimer)
        {
            int timeout;
            pvtGetChildValue(app->hVal, app->h245Conf, __h245(channelsTimeout), &timeout, NULL);
            newChannelArray[i]->pTimer = RvH323TimerStart(cmGetTimersHandle((HAPP)app), channelTimeoutEventsHandler, (void*)&newChannelArray[i], timeout * 1000);
        }
        newChannelArray[i]->pRequestCloseTimer = NULL;
        newChannelArray[i]->pMediaLoopTimer = NULL;

        newChannelArray[i]->hCtrl = (HCONTROL)newControl;
    }

    if(chanArraySize > 0)
        cmiSetChannelListForCall((HCALL)newCall, (HCHAN)newChannelArray[0]);
    else
        cmiSetChannelListForCall((HCALL)newCall, (HCHAN)NULL);

    return RV_OK;
}


void delCall(cmElem * app, callElem * call)
{
    /* delete the call */
    H245Channel * curChan, * nextChan;

    /* remove the previous property */
    if(call->property >= 0)
        pvtDelete(app->hVal, call->property);

    /* remove the previous cat entry */
    if(call->hCatCall)
        catDelete(app->hCat, call->hCatCall);

    /* remove the previous session */
    if(call->hsTransSession)
    {
        cmTransSession * session = (cmTransSession *)call->hsTransSession;

        if(session->hashEntry)
        {
            cmTransGlobals * transGlobals = (cmTransGlobals *)app->hTransport;

            hashDelete(transGlobals->hHashSessions, session->hashEntry);

            if(session->H245Connection)
                closeHostInternal((HSTRANSHOST)session->H245Connection, RV_FALSE);
            if(session->Q931Connection)
                closeHostInternal((HSTRANSHOST)session->Q931Connection, RV_FALSE);
            if(session->annexEConnection)
                closeHostInternal((HSTRANSHOST)session->annexEConnection, RV_FALSE);

            emaDelete((EMAElement)call->hsTransSession);
        }
    }

    /* remove the previous channels */
    nextChan = curChan = (H245Channel *) cmiGetChannelListForCall((HCALL)call);
    while(nextChan != NULL)
    {
        nextChan = curChan->pNext;
        emaDelete((EMAElement)curChan);
    }

    emaDelete((EMAElement)call);
}


RVAPI RvStatus RVCALLCONV RvH323HaDelCall(
    IN HAPP      hApp,
    IN HAPPCALL  haCall
    )
{
    cmElem * app = (cmElem *) hApp;
    EMAElement emaElem = NULL;
    callElem * call;

    /* go over all the calls in the EMA */
    while((emaElem = emaGetNext(app->hCalls, emaElem)) != NULL)
    {
        /* see if this is the call we want */
        if(haCall == (HAPPCALL)emaGetApplicationHandle(emaElem))
        {
            call = (callElem *) emaElem;

⌨️ 快捷键说明

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