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

📄 transutil.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
 *                                                  have a session ).
 *
 **************************************************************************************/
RvBool findSessionByMessage(
    cmTransGlobals *transGlobals,
    cmTransHost    *host,
    int            pvtNode,
    RvBool         isAnnexE,
    cmTransSession **session)
{
    RvUint16        CRV = 0;
    RvInt32         temp = 0;
    RvUint8         callID[16];
    RvUint8         nullCallID[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    int             msgType;
    RvBool          bNullCallId = RV_FALSE;
    int             res;

    void            *loc;
    sessionKey      key;
    RvBool          found;

    /* check what type of Q.931 message we have here */
    msgType = pvtGetChildTagByPath(transGlobals->hPvt, pvtNode, "message", 1);
    if (msgType < 0)
    {
        RvLogError(&transGlobals->hLog,
            (&transGlobals->hLog, "findSessionByMessage failed to get message type tag"));
        return RV_FALSE;
    }

    /* get the CRV and callID (if exists) of the message and build the key for CAT */
    __pvtGetByFieldIds(res, transGlobals->hPvt,pvtNode,
                        {
                          _q931(callReferenceValue)
                          _q931(twoBytes)
                          LAST_TOKEN
                        },
                        NULL,(RvInt32 *)&temp,NULL);
    CRV = (RvUint16)temp;


    __pvtGetNodeIdByFieldIds(res, transGlobals->hPvt, pvtNode,
                            { _q931(message)
                              _anyField
                              _q931(userUser)
                              _q931(h323_UserInformation)
                              _q931(h323_uu_pdu)
                              _q931(h323_message_body)
                              _anyField
                              _q931(callIdentifier)
                              _q931(guid)
                              LAST_TOKEN
                            });
    if (res>=0)
    {
        pvtGetString(transGlobals->hPvt, res, sizeof(callID), (char *)callID);
        if (memcmp(nullCallID, callID, sizeof(callID))==0)
            bNullCallId = RV_TRUE;
    }
    else
    {
        bNullCallId = RV_TRUE;
        memcpy(callID, nullCallID, sizeof(callID));
    }

    /* check if this is a message not attached to a particular session,
       i.e. CRV = 0, callID = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} */

    if ( (CRV == 0) && (bNullCallId) )
    {
        *session = NULL;

        RvLogInfo(&transGlobals->hLog,
            (&transGlobals->hLog, "findSessionByMessage found a general message"));
        return RV_TRUE;
    }

    if (!*session)
    {
        /* no session exists yet, this is an incoming message */

        /* since its an incoming message change the bit direction of the CRV */
        CRV ^= 0x8000;

        /* look for the entry in the hash */
        key.CRV  = CRV;
        found    = RV_FALSE;

        RvLogInfo(&transGlobals->hLog,
            (&transGlobals->hLog,
                "findSessionByMessage incoming CRV (findHash) = %x host=%d(%x)",
                key.CRV,emaGetIndex((EMAElement)host), host));

        /* go over all the sessions with the same CRV from this host, hopefully
           there is only one (in most cases) */
        RvLockGet(&transGlobals->lockHash);
        for (loc = hashFind(transGlobals->hHashSessions,(void *)&key);
             (loc != NULL) && (!found);
             loc = hashFindNext(transGlobals->hHashSessions, (void *)&key, loc))
        {
            cmTransSession *sess = *(cmTransSession **)hashGetElement(transGlobals->hHashSessions,
                                                                      loc);
            /* check that the session has the same call ID as the message */
            if (memcmp(sess->callId, callID, sizeof(callID)) == 0)
            {
                *session = sess;
                found = RV_TRUE;
            }
            else
            /* if we don't have call ID (version 1 or CRV0 messages), check that
               the session is from our host */
            if (bNullCallId)
            {
                /* check first for the TPKT connection */
                if  ( (!isAnnexE) &&
                      (sess->Q931Connection) &&
                      (sess->Q931Connection->remoteAddress.ip   == host->remoteAddress.ip) &&
                      (sess->Q931Connection->remoteAddress.port == host->remoteAddress.port) )
                {
                    *session = sess;
                    found = RV_TRUE;
                }

                /* our last chance that it's from the annex E connection */
                if  ( (isAnnexE) &&
                      (sess->annexEConnection) &&
                      (sess->annexEConnection->remoteAddress.ip   == host->remoteAddress.ip) &&
                      (sess->annexEConnection->remoteAddress.port == host->remoteAddress.port) )
                {
                    *session = sess;
                    found = RV_TRUE;
                }
            }
        }
        RvLockRelease(&transGlobals->lockHash);

        /* no session was found, this must be a new incoming message */
        if (!found)
        {
            TRANSERR err = cmTransErr;

            /* we may create new session only for new incoming SETUP message */
            if (msgType == cmQ931setup)
            {
                /* create a new session */
                RvMutexLock(&transGlobals->lockSessionsList);
                err = cmTransCreateSession((HAPPTRANS)transGlobals,
                                            NULL,
                                            (HSTRANSSESSION *)session);
                RvMutexUnlock(&transGlobals->lockSessionsList);
            }
            else
            {
                RvLogWarning(&transGlobals->hLog,
                    (&transGlobals->hLog,
                        "findSessionByMessage new incoming message which is not SETUP, type=%d", msgType));
                return RV_FALSE;
            }

            if (err != cmTransOK)
            {
                RvLogError(&transGlobals->hLog,
                    (&transGlobals->hLog,
                        "findSessionByMessage failed to create a new session"));
                return RV_FALSE;
            }
            else
            {
                RvLogInfo(&transGlobals->hLog,
                    (&transGlobals->hLog,
                        "findSessionByMessage created a new session %d(%x)",
                        emaGetIndex((EMAElement)*session), *session));


                /* add the new session to the hash table */
                key.CRV  = CRV;
                RvLogInfo(&transGlobals->hLog,
                    (&transGlobals->hLog,
                        "findSessionByMessage incoming CRV (AddHash)= %x host=%d(%x) session=%d(%x)",
                        key.CRV,emaGetIndex((EMAElement)host), host, emaGetIndex((EMAElement)*session), *session));
                loc = hashAdd(transGlobals->hHashSessions,(void *)&key,(void *)session, RV_FALSE);
                if (!loc)
                {
                    cmTransCloseSession((HSTRANSSESSION)*session);

                    RvLogError(&transGlobals->hLog,
                        (&transGlobals->hLog,
                            "findSessionByMessage failed to add session to hash table"));
                    return RV_FALSE;
                }
                else
                {
                    /* update the sessions callIs and CRV and mark it as incoming session*/
                    memcpy((*session)->callId, callID, sizeof(callID));
                    (*session)->CRV = CRV;
                    (*session)->hashEntry = loc;
                    (*session)->outgoing = RV_FALSE;
                }
            }
        }
        else
        if (msgType == cmQ931setup)
        {
            RvLogError(&transGlobals->hLog,
                (&transGlobals->hLog,
                    "findSessionByMessage found session %d (%x) for an incoming setup message !!!!",
                    emaGetIndex((EMAElement)*session), *session));
        }


        /* connect the session to the host */
        if (!isAnnexE)
            (*session)->Q931Connection   = host;
        else
            (*session)->annexEConnection = host;

        /* add the session to the hosts list of session.
           Do it just for the first time, i.e. when the SETUP
           message arrives.
           (in case of TPKT & annex E race, done just for TPKT host,
           for annex E this will be done if and when it will win the race */
        if ( (!isAnnexE) && (msgType == cmQ931setup) )
        {
            RvMutexLock(&transGlobals->lockSessionsList);
            /* connect the session to the host */
            if (*session != host->firstSession)
            {
                (*session)->nextSession = host->firstSession;
                if ((*session)->nextSession)
                    (*session)->nextSession->prevSession = (*session);
                host->firstSession = (*session);
            }
            else
                printf("transutil(1):insert same seesion as firstSession:%x\n", session);
            RvMutexUnlock(&transGlobals->lockSessionsList);
        }

        RvLogInfo(&transGlobals->hLog,
            (&transGlobals->hLog, "findSessionByMessage found session %d (%x)",
                emaGetIndex((EMAElement)*session), *session));


    }
    else
    {
        /* if session exists this means this is a first outgoing message on a session
            created by the user, add it to the hash table
        */
        if (!(*session)->hashEntry)
        {
            void *loc  = NULL;

            key.CRV  = CRV;

            RvLogInfo(&transGlobals->hLog,
                (&transGlobals->hLog,
                    "findSessionByMessage outgoing CRV (AddHAsh) = %x host=%d(%x) session=%d(%x)",
                    key.CRV,emaGetIndex((EMAElement)host), host, emaGetIndex((EMAElement)*session), *session));

            loc = hashAdd(transGlobals->hHashSessions,(void *)&key,(void *)session, RV_FALSE);

            if (!loc)
            {
                cmTransCloseSession((HSTRANSSESSION)*session);

                RvLogError(&transGlobals->hLog,
                    (&transGlobals->hLog,
                        "findSessionByMessage failed to add session to hash table"));
                return RV_FALSE;
            }
            else
            {
                memcpy((*session)->callId, callID, sizeof(callID));
                (*session)->CRV = CRV;
                (*session)->hashEntry = loc;
            }
        }
    }

    return RV_TRUE;
}

/**************************************************************************************
 * setRemoteAddress
 *
 * Purpose: sets the remote address to the host and adds an entry to the host hash table
 *
 * Input:   host            - The host to which the address is to be set.
 *          remoteAddress   - The address to be set.
 *
 * Return Value: cmTransOK - if all is well; cmTranErr - otherwise
 *
 **************************************************************************************/
TRANSERR setRemoteAddress(cmTransHost *host, cmTransportAddress *remoteAddress)
{
    void *res;
    hostKey key;

    /* retrieve the transport module global area */
    cmTransGlobals *transGlobals = (cmTransGlobals *)emaGetUserData((EMAElement)host);

    if (!remoteAddress)
        return cmTransErr;

    if (remoteAddress->type != -1)
    {
        host->remoteAddress = *remoteAddress;

        key.ip   = host->remoteAddress.ip;
        key.port = (RvUint32)host->remoteAddress.port;
        key.type = (host->annexEUsageMode != cmTransNoAnnexE);

        RvLockGet(&transGlobals->lockHash);
        res = hashAdd(transGlobals->hHashHosts,(void *)&key, (void *)&host, RV_FALSE);
        RvLockRelease(&transGlobals->lockHash);
        RvLogInfo(&transGlobals->hLog,
            (&transGlobals->hLog, "hashAdd = %x [hostKey: ip=%x port=%d type=%d]",
                res,key.ip, key.port, key.type));

        if (!res)
        {
            RvLogError(&transGlobals->hLog,
                (&transGlobals->hLog,
                    "setRemoteAddress failed on updating hosts hash table"));
            return cmTransErr;
     

⌨️ 快捷键说明

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